{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeApplications #-}

module HaskellWorks.Polysemy.Amazonka
  ( runReaderAwsEnvDiscover,
    sendAws,
  ) where

import           Control.Monad.IO.Class
import           Control.Monad.Trans.Resource
import           Data.Typeable

import qualified Amazonka                     as AWS
import           HaskellWorks.Prelude
import           Polysemy
import           Polysemy.Error
import           Polysemy.Reader
import qualified System.IO                    as IO

runReaderAwsEnvDiscover :: ()
  => Member (Embed IO) r
  => Sem (Reader AWS.Env : r) a
  -> Sem r a
runReaderAwsEnvDiscover :: forall (r :: EffectRow) a.
Member (Embed IO) r =>
Sem (Reader Env : r) a -> Sem r a
runReaderAwsEnvDiscover Sem (Reader Env : r) a
f = do
  Logger
logger' <- IO Logger -> Sem r Logger
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed (IO Logger -> Sem r Logger) -> IO Logger -> Sem r Logger
forall a b. (a -> b) -> a -> b
$ LogLevel -> Handle -> IO Logger
forall (m :: * -> *). MonadIO m => LogLevel -> Handle -> m Logger
AWS.newLogger LogLevel
AWS.Debug Handle
IO.stdout
  Env
discoveredAwsEnv <- IO Env -> Sem r Env
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed (IO Env -> Sem r Env) -> IO Env -> Sem r Env
forall a b. (a -> b) -> a -> b
$ (EnvNoAuth -> IO Env) -> IO Env
forall (m :: * -> *). MonadIO m => (EnvNoAuth -> m Env) -> m Env
AWS.newEnv EnvNoAuth -> IO Env
forall (m :: * -> *) (withAuth :: * -> *).
(MonadCatch m, MonadIO m, Foldable withAuth) =>
Env' withAuth -> m Env
AWS.discover
  let awsEnv :: Env
awsEnv = Env
discoveredAwsEnv { AWS.logger = logger' }
  Env -> Sem (Reader Env : r) a -> Sem r a
forall i (r :: EffectRow) a. i -> Sem (Reader i : r) a -> Sem r a
runReader Env
awsEnv Sem (Reader Env : r) a
f

sendAws :: ()
  => AWS.AWSRequest a
  => Member (Embed m) r
  => Member (Error AWS.Error) r
  => Member (Reader AWS.Env) r
  => MonadIO m
  => Typeable (AWS.AWSResponse a)
  => Typeable a
  => a
  -> Sem r (AWS.AWSResponse a)
sendAws :: forall a (m :: * -> *) (r :: EffectRow).
(AWSRequest a, Member (Embed m) r, Member (Error Error) r,
 Member (Reader Env) r, MonadIO m, Typeable (AWSResponse a),
 Typeable a) =>
a -> Sem r (AWSResponse a)
sendAws a
req = do
  Env
envAws <- forall i (r :: EffectRow). Member (Reader i) r => Sem r i
ask @AWS.Env
  Either Error (AWSResponse a)
result <- m (Either Error (AWSResponse a))
-> Sem r (Either Error (AWSResponse a))
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed (m (Either Error (AWSResponse a))
 -> Sem r (Either Error (AWSResponse a)))
-> m (Either Error (AWSResponse a))
-> Sem r (Either Error (AWSResponse a))
forall a b. (a -> b) -> a -> b
$ IO (Either Error (AWSResponse a))
-> m (Either Error (AWSResponse a))
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Either Error (AWSResponse a))
 -> m (Either Error (AWSResponse a)))
-> IO (Either Error (AWSResponse a))
-> m (Either Error (AWSResponse a))
forall a b. (a -> b) -> a -> b
$ ResourceT IO (Either Error (AWSResponse a))
-> IO (Either Error (AWSResponse a))
forall (m :: * -> *) a. MonadUnliftIO m => ResourceT m a -> m a
runResourceT (ResourceT IO (Either Error (AWSResponse a))
 -> IO (Either Error (AWSResponse a)))
-> ResourceT IO (Either Error (AWSResponse a))
-> IO (Either Error (AWSResponse a))
forall a b. (a -> b) -> a -> b
$ Env -> a -> ResourceT IO (Either Error (AWSResponse a))
forall (m :: * -> *) a.
(MonadResource m, AWSRequest a, Typeable a,
 Typeable (AWSResponse a)) =>
Env -> a -> m (Either Error (AWSResponse a))
AWS.sendEither Env
envAws a
req
  Either Error (AWSResponse a) -> Sem r (AWSResponse a)
forall e (r :: EffectRow) a.
Member (Error e) r =>
Either e a -> Sem r a
fromEither Either Error (AWSResponse a)
result