module Control.Monad.Web
  ( MonadWeb
  , doRequest
  , makeManager
  ) where

import Auth.Types (addUserAgent)
import Control.Monad.Except (ExceptT)
import Control.Monad.Logger (LoggingT)
import Control.Monad.Reader (ReaderT)
import Control.Monad.Trans.Class (lift)
import Data.ByteString.Lazy qualified as LBS
import Data.Text (Text)
import Network.HTTP.Client (managerModifyRequest)
import Network.HTTP.Client.TLS (tlsManagerSettings)
import Network.HTTP.Conduit (Manager, Request, Response, httpLbs, newManager)

class Monad m =>
      MonadWeb m
  where
  makeManager :: m Manager
  doRequest :: Manager -> Request -> m (Either Text (Response LBS.ByteString))

instance MonadWeb IO where
  makeManager :: IO Manager
makeManager = ManagerSettings -> IO Manager
newManager (ManagerSettings -> IO Manager) -> ManagerSettings -> IO Manager
forall a b. (a -> b) -> a -> b
$ ManagerSettings
tlsManagerSettings {managerModifyRequest :: Request -> IO Request
managerModifyRequest = Request -> IO Request
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Request -> IO Request)
-> (Request -> Request) -> Request -> IO Request
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Request -> Request
addUserAgent}
  doRequest :: Manager -> Request -> IO (Either Text (Response ByteString))
doRequest Manager
manager Request
request = Response ByteString -> Either Text (Response ByteString)
forall a b. b -> Either a b
Right (Response ByteString -> Either Text (Response ByteString))
-> IO (Response ByteString)
-> IO (Either Text (Response ByteString))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Request -> Manager -> IO (Response ByteString)
forall (m :: * -> *).
MonadIO m =>
Request -> Manager -> m (Response ByteString)
httpLbs Request
request Manager
manager

instance MonadWeb m => MonadWeb (LoggingT m) where
  makeManager :: LoggingT m Manager
makeManager = m Manager -> LoggingT m Manager
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m Manager
forall (m :: * -> *). MonadWeb m => m Manager
makeManager
  doRequest :: Manager
-> Request -> LoggingT m (Either Text (Response ByteString))
doRequest Manager
manager = m (Either Text (Response ByteString))
-> LoggingT m (Either Text (Response ByteString))
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Either Text (Response ByteString))
 -> LoggingT m (Either Text (Response ByteString)))
-> (Request -> m (Either Text (Response ByteString)))
-> Request
-> LoggingT m (Either Text (Response ByteString))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Manager -> Request -> m (Either Text (Response ByteString))
forall (m :: * -> *).
MonadWeb m =>
Manager -> Request -> m (Either Text (Response ByteString))
doRequest Manager
manager


instance MonadWeb m => MonadWeb (ExceptT e m) where
  makeManager :: ExceptT e m Manager
makeManager = m Manager -> ExceptT e m Manager
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m Manager
forall (m :: * -> *). MonadWeb m => m Manager
makeManager
  doRequest :: Manager
-> Request -> ExceptT e m (Either Text (Response ByteString))
doRequest Manager
manager = m (Either Text (Response ByteString))
-> ExceptT e m (Either Text (Response ByteString))
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Either Text (Response ByteString))
 -> ExceptT e m (Either Text (Response ByteString)))
-> (Request -> m (Either Text (Response ByteString)))
-> Request
-> ExceptT e m (Either Text (Response ByteString))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Manager -> Request -> m (Either Text (Response ByteString))
forall (m :: * -> *).
MonadWeb m =>
Manager -> Request -> m (Either Text (Response ByteString))
doRequest Manager
manager

instance MonadWeb m => MonadWeb (ReaderT a m) where
  makeManager :: ReaderT a m Manager
makeManager = m Manager -> ReaderT a m Manager
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m Manager
forall (m :: * -> *). MonadWeb m => m Manager
makeManager
  doRequest :: Manager
-> Request -> ReaderT a m (Either Text (Response ByteString))
doRequest Manager
manager = m (Either Text (Response ByteString))
-> ReaderT a m (Either Text (Response ByteString))
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Either Text (Response ByteString))
 -> ReaderT a m (Either Text (Response ByteString)))
-> (Request -> m (Either Text (Response ByteString)))
-> Request
-> ReaderT a m (Either Text (Response ByteString))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Manager -> Request -> m (Either Text (Response ByteString))
forall (m :: * -> *).
MonadWeb m =>
Manager -> Request -> m (Either Text (Response ByteString))
doRequest Manager
manager