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

import           Data.Aeson                      (FromJSON (..), ToJSON (..))
import           Data.Monoid                     ((<>))
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
token = Scheme -> String -> Int -> String -> BaseUrl
BaseUrl Scheme
Https "api.telegram.org" 443
  (Text -> String
Text.unpack ("/bot" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Token -> Text
forall a. ToHttpApiData a => a -> Text
toUrlPiece Token
token))

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

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

data Response a = Response
  { Response a -> Bool
responseOk          :: Bool
  , Response a -> Maybe Text
responseDescription :: Maybe Text
  , Response a -> a
responseResult      :: a
  , Response a -> Maybe Integer
responseErrorCode   :: Maybe Integer
  , Response a -> Maybe ResponseParameters
responseParameters  :: Maybe ResponseParameters
  } deriving (Int -> Response a -> ShowS
[Response a] -> ShowS
Response a -> String
(Int -> Response a -> ShowS)
-> (Response a -> String)
-> ([Response a] -> ShowS)
-> Show (Response a)
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 x. Response a -> Rep (Response a) x)
-> (forall x. Rep (Response a) x -> Response a)
-> Generic (Response a)
forall x. Rep (Response a) x -> Response a
forall x. Response a -> Rep (Response a) x
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 = Response a -> Value
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 = Value -> Parser (Response a)
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
(Token -> Token -> Bool) -> (Token -> Token -> Bool) -> Eq Token
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
(Int -> Token -> ShowS)
-> (Token -> String) -> ([Token] -> ShowS) -> Show Token
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 -> ByteString
Token -> Builder
Token -> Text
(Token -> Text)
-> (Token -> Builder)
-> (Token -> ByteString)
-> (Token -> Text)
-> ToHttpApiData Token
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
(Text -> Either Text Token)
-> (ByteString -> Either Text Token)
-> (Text -> Either Text Token)
-> FromHttpApiData 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
(Token -> Value)
-> (Token -> Encoding)
-> ([Token] -> Value)
-> ([Token] -> Encoding)
-> ToJSON Token
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
(Value -> Parser Token)
-> (Value -> Parser [Token]) -> FromJSON 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
(String -> Token) -> IsString Token
forall a. (String -> a) -> IsString a
fromString :: String -> Token
$cfromString :: String -> Token
IsString)