-- Copyright (c) 2020-present, EMQX, Inc.
-- All rights reserved.
--
-- This source code is distributed under the terms of a MIT license,
-- found in the LICENSE file.

{-# LANGUAGE CPP  #-}
{-# LANGUAGE OverloadedStrings #-}

-- | Connection pool for HTTP connection. User should import Database.ClickHouseDriver.HTTP instead

module Database.ClickHouseDriver.HTTP.Connection (
    httpConnect,
    httpConnectDb,
    defaultHttpConnection,
    HttpConnection(..),
    createHttpPool
) where
                                
import Network.HTTP.Client
    ( defaultManagerSettings, newManager)
import Database.ClickHouseDriver.HTTP.Types
    ( HttpConnection(..),
      HttpParams(HttpParams, httpUsername, httpPort, httpPassword,
                 httpHost, httpDatabase) ) 
import Data.Default.Class ( Default(..) )
import Data.Pool ( createPool, Pool )
import Data.Time.Clock ( NominalDiffTime )

#define DEFAULT_USERNAME  "default"
#define DEFAULT_HOST_NAME "localhost"
#define DEFAULT_PASSWORD  ""
--TODO change default password to ""

defaultHttpConnection :: IO (HttpConnection)
defaultHttpConnection :: IO HttpConnection
defaultHttpConnection = String -> String -> Int -> String -> IO HttpConnection
httpConnect DEFAULT_USERNAME DEFAULT_PASSWORD 8123 DEFAULT_HOST_NAME

instance Default HttpParams where
  def :: HttpParams
def = HttpParams :: String -> Int -> String -> String -> Maybe String -> HttpParams
HttpParams{
     httpHost :: String
httpHost = DEFAULT_HOST_NAME,
     httpPassword :: String
httpPassword = DEFAULT_PASSWORD,
     httpPort :: Int
httpPort = Int
8123,
     httpUsername :: String
httpUsername = DEFAULT_USERNAME,
     httpDatabase :: Maybe String
httpDatabase = Maybe String
forall a. Maybe a
Nothing
  }

createHttpPool :: HttpParams
                ->Int
                ->NominalDiffTime
                ->Int
                ->IO(Pool HttpConnection)
createHttpPool :: HttpParams
-> Int -> NominalDiffTime -> Int -> IO (Pool HttpConnection)
createHttpPool HttpParams{
                httpHost :: HttpParams -> String
httpHost=String
host,
                httpPassword :: HttpParams -> String
httpPassword = String
password,
                httpPort :: HttpParams -> Int
httpPort = Int
port,
                httpUsername :: HttpParams -> String
httpUsername = String
user,
                httpDatabase :: HttpParams -> Maybe String
httpDatabase = Maybe String
db
              } 
  = IO HttpConnection
-> (HttpConnection -> IO ())
-> Int
-> NominalDiffTime
-> Int
-> IO (Pool HttpConnection)
forall a.
IO a
-> (a -> IO ()) -> Int -> NominalDiffTime -> Int -> IO (Pool a)
createPool(
      do
        String
-> String -> Int -> String -> Maybe String -> IO HttpConnection
httpConnectDb String
user String
password Int
port String
host Maybe String
db
  )(\HttpConnection
_->() -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ())


httpConnect :: String->String->Int->String->IO(HttpConnection)
httpConnect :: String -> String -> Int -> String -> IO HttpConnection
httpConnect String
user String
password Int
port String
host = 
  String
-> String -> Int -> String -> Maybe String -> IO HttpConnection
httpConnectDb String
user String
password Int
port String
host Maybe String
forall a. Maybe a
Nothing

httpConnectDb :: String->String->Int->String->Maybe String->IO(HttpConnection)
httpConnectDb :: String
-> String -> Int -> String -> Maybe String -> IO HttpConnection
httpConnectDb String
user String
password Int
port String
host Maybe String
database = do
  Manager
mng <- ManagerSettings -> IO Manager
newManager ManagerSettings
defaultManagerSettings
  HttpConnection -> IO HttpConnection
forall (m :: * -> *) a. Monad m => a -> m a
return HttpConnection :: HttpParams -> Manager -> HttpConnection
HttpConnection {
    httpParams :: HttpParams
httpParams = HttpParams :: String -> Int -> String -> String -> Maybe String -> HttpParams
HttpParams {
      httpHost :: String
httpHost = String
host,
      httpPassword :: String
httpPassword = String
password,
      httpPort :: Int
httpPort = Int
port,
      httpUsername :: String
httpUsername = String
user,
      httpDatabase :: Maybe String
httpDatabase = Maybe String
database
    },
      httpManager :: Manager
httpManager = Manager
mng
  }