{-# LANGUAGE CPP                        #-}
{-# LANGUAGE DeriveGeneric              #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings          #-}
module Telegram.Bot.API.MakingRequests where

import           Data.Aeson                      (FromJSON (..), ToJSON (..))
#if defined(MIN_VERSION_GLASGOW_HASKELL)
#if MIN_VERSION_GLASGOW_HASKELL(8,6,2,0)
#else
import           Data.Monoid                     ((<>))
#endif
#endif
import           Data.String                     (IsString)
import           Data.Text                       (Text)
import qualified Data.Text                       as Text
import           GHC.Generics                    (Generic)
import           Network.HTTP.Client             (newManager)
import           Network.HTTP.Client.TLS         (tlsManagerSettings)
import           Servant.Client                  hiding (Response)
import           Web.HttpApiData                 (FromHttpApiData,
                                                  ToHttpApiData (..))

import           Telegram.Bot.API.Internal.Utils
import           Telegram.Bot.API.Types

botBaseUrl :: Token -> BaseUrl
botBaseUrl :: Token -> BaseUrl
botBaseUrl Token
token = Scheme -> String -> Int -> String -> BaseUrl
BaseUrl Scheme
Https String
"api.telegram.org" Int
443
  (Text -> String
Text.unpack (Text
"/bot" forall a. Semigroup a => a -> a -> a
<> forall a. ToHttpApiData a => a -> Text
toUrlPiece Token
token))

botBaseUrlTest :: Token -> BaseUrl
botBaseUrlTest :: Token -> BaseUrl
botBaseUrlTest Token
token = Scheme -> String -> Int -> String -> BaseUrl
BaseUrl Scheme
Https String
"api.telegram.org" Int
443
  (Text -> String
Text.unpack (Text
"/bot" forall a. Semigroup a => a -> a -> a
<> forall a. ToHttpApiData a => a -> Text
toUrlPiece Token
token forall a. Semigroup a => a -> a -> a
<> Text
"/test"))

defaultTelegramClientEnv :: Token -> IO ClientEnv
defaultTelegramClientEnv :: Token -> IO ClientEnv
defaultTelegramClientEnv Token
token = Manager -> BaseUrl -> ClientEnv
mkClientEnv
  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ManagerSettings -> IO Manager
newManager ManagerSettings
tlsManagerSettings
  forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (f :: * -> *) a. Applicative f => a -> f a
pure (Token -> BaseUrl
botBaseUrl Token
token)

defaultTelegramClientEnvTest :: Token -> IO ClientEnv
defaultTelegramClientEnvTest :: Token -> IO ClientEnv
defaultTelegramClientEnvTest Token
token = Manager -> BaseUrl -> ClientEnv
mkClientEnv
  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ManagerSettings -> IO Manager
newManager ManagerSettings
tlsManagerSettings
  forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (f :: * -> *) a. Applicative f => a -> f a
pure (Token -> BaseUrl
botBaseUrlTest Token
token)

defaultRunBot :: Token -> ClientM a -> IO (Either ClientError a)
defaultRunBot :: forall a. Token -> ClientM a -> IO (Either ClientError a)
defaultRunBot Token
token ClientM a
bot = do
  ClientEnv
env <- Token -> IO ClientEnv
defaultTelegramClientEnv Token
token
  forall a. ClientM a -> ClientEnv -> IO (Either ClientError a)
runClientM ClientM a
bot ClientEnv
env

defaultRunBotTest :: Token -> ClientM a -> IO (Either ClientError a)
defaultRunBotTest :: forall a. Token -> ClientM a -> IO (Either ClientError a)
defaultRunBotTest Token
token ClientM a
bot = do
  ClientEnv
env <- Token -> IO ClientEnv
defaultTelegramClientEnvTest Token
token
  forall a. ClientM a -> ClientEnv -> IO (Either ClientError a)
runClientM ClientM a
bot ClientEnv
env

data Response a = Response
  { forall a. Response a -> Bool
responseOk          :: Bool
  , forall a. Response a -> Maybe Text
responseDescription :: Maybe Text
  , forall a. Response a -> a
responseResult      :: a
  , forall a. Response a -> Maybe Integer
responseErrorCode   :: Maybe Integer
  , forall a. Response a -> Maybe ResponseParameters
responseParameters  :: Maybe ResponseParameters
  } deriving (Int -> Response a -> ShowS
forall a. Show a => Int -> Response a -> ShowS
forall a. Show a => [Response a] -> ShowS
forall a. Show a => Response a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Response a] -> ShowS
$cshowList :: forall a. Show a => [Response a] -> ShowS
show :: Response a -> String
$cshow :: forall a. Show a => Response a -> String
showsPrec :: Int -> Response a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Response a -> ShowS
Show, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Response a) x -> Response a
forall a x. Response a -> Rep (Response a) x
$cto :: forall a x. Rep (Response a) x -> Response a
$cfrom :: forall a x. Response a -> Rep (Response a) x
Generic)

instance ToJSON   a => ToJSON   (Response a) where toJSON :: Response a -> Value
toJSON = forall a (d :: Meta) (f :: * -> *).
(Generic a, GToJSON Zero (Rep a), Rep a ~ D1 d f, Datatype d) =>
a -> Value
gtoJSON
instance FromJSON a => FromJSON (Response a) where parseJSON :: Value -> Parser (Response a)
parseJSON = forall a (d :: Meta) (f :: * -> *).
(Generic a, GFromJSON Zero (Rep a), Rep a ~ D1 d f, Datatype d) =>
Value -> Parser a
gparseJSON

newtype Token = Token Text
  deriving (Token -> Token -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Token -> Token -> Bool
$c/= :: Token -> Token -> Bool
== :: Token -> Token -> Bool
$c== :: Token -> Token -> Bool
Eq, Int -> Token -> ShowS
[Token] -> ShowS
Token -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Token] -> ShowS
$cshowList :: [Token] -> ShowS
show :: Token -> String
$cshow :: Token -> String
showsPrec :: Int -> Token -> ShowS
$cshowsPrec :: Int -> Token -> ShowS
Show, Token -> Builder
Token -> ByteString
Token -> Text
forall a.
(a -> Text)
-> (a -> Builder)
-> (a -> ByteString)
-> (a -> Text)
-> ToHttpApiData a
toQueryParam :: Token -> Text
$ctoQueryParam :: Token -> Text
toHeader :: Token -> ByteString
$ctoHeader :: Token -> ByteString
toEncodedUrlPiece :: Token -> Builder
$ctoEncodedUrlPiece :: Token -> Builder
toUrlPiece :: Token -> Text
$ctoUrlPiece :: Token -> Text
ToHttpApiData, ByteString -> Either Text Token
Text -> Either Text Token
forall a.
(Text -> Either Text a)
-> (ByteString -> Either Text a)
-> (Text -> Either Text a)
-> FromHttpApiData a
parseQueryParam :: Text -> Either Text Token
$cparseQueryParam :: Text -> Either Text Token
parseHeader :: ByteString -> Either Text Token
$cparseHeader :: ByteString -> Either Text Token
parseUrlPiece :: Text -> Either Text Token
$cparseUrlPiece :: Text -> Either Text Token
FromHttpApiData, [Token] -> Encoding
[Token] -> Value
Token -> Encoding
Token -> Value
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [Token] -> Encoding
$ctoEncodingList :: [Token] -> Encoding
toJSONList :: [Token] -> Value
$ctoJSONList :: [Token] -> Value
toEncoding :: Token -> Encoding
$ctoEncoding :: Token -> Encoding
toJSON :: Token -> Value
$ctoJSON :: Token -> Value
ToJSON, Value -> Parser [Token]
Value -> Parser Token
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [Token]
$cparseJSONList :: Value -> Parser [Token]
parseJSON :: Value -> Parser Token
$cparseJSON :: Value -> Parser Token
FromJSON, String -> Token
forall a. (String -> a) -> IsString a
fromString :: String -> Token
$cfromString :: String -> Token
IsString)