-- 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 Data.Default.Class (Default (..))
import Data.Pool (Pool, createPool)
import Data.Time.Clock (NominalDiffTime)
import Database.ClickHouseDriver.HTTP.Types
  ( HttpConnection (..),
    HttpParams
      ( HttpParams,
        httpDatabase,
        httpHost,
        httpPassword,
        httpPort,
        httpUsername
      ),
  )
import Network.HTTP.Client
  ( defaultManagerSettings,
    newManager,
  )

#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
      }