{- HLINT ignore "Use let" -}

module Effectful.Zoo.Amazonka.Static
  ( Amazonka,
    runAmazonka,
    withAmazonka,
    localAmazonka,
    askAwsEnv,
    sendAws,
    lazySendAws,
  ) where

import Amazonka qualified as AWS
import Control.Monad.IO.Class
import Control.Monad.Trans.Resource
import Data.Typeable
import Effectful
import Effectful.Dispatch.Static
import Effectful.Error.Static
import Effectful.Zoo.Amazonka.Data
import Effectful.Zoo.Core
import Effectful.Zoo.DataLog.Api
import Effectful.Zoo.DataLog.Dynamic
import Effectful.Zoo.Lazy.Dynamic
import GHC.Stack qualified as GHC
import HaskellWorks.Prelude

data Amazonka :: Effect

type instance DispatchOf Amazonka = Static WithSideEffects

newtype instance StaticRep Amazonka = Amazonka AwsEnv

runAmazonka :: forall a r. ()
  => r <: IOE
  => AwsEnv
  -> Eff (Amazonka : r) a
  -> Eff r a
runAmazonka :: forall a (r :: [Effect]).
(r <: IOE) =>
AwsEnv -> Eff (Amazonka : r) a -> Eff r a
runAmazonka AwsEnv
awsEnv =
  StaticRep Amazonka -> Eff (Amazonka : r) a -> Eff r a
forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect])
       a.
(HasCallStack, DispatchOf e ~ 'Static sideEffects,
 MaybeIOE sideEffects es) =>
StaticRep e -> Eff (e : es) a -> Eff es a
evalStaticRep (StaticRep Amazonka -> Eff (Amazonka : r) a -> Eff r a)
-> StaticRep Amazonka -> Eff (Amazonka : r) a -> Eff r a
forall a b. (a -> b) -> a -> b
$ AwsEnv -> StaticRep Amazonka
Amazonka AwsEnv
awsEnv

withAmazonka :: forall r a. ()
  => HasCallStack
  => r <: IOE
  => (AwsEnv -> AwsEnv)
  -> Eff (Amazonka : r) a
  -> Eff (Amazonka : r) a
withAmazonka :: forall (r :: [Effect]) a.
(HasCallStack, r <: IOE) =>
(AwsEnv -> AwsEnv) -> Eff (Amazonka : r) a -> Eff (Amazonka : r) a
withAmazonka AwsEnv -> AwsEnv
f Eff (Amazonka : r) a
m = do
  Amazonka AwsEnv
awsEnv <- Eff (Amazonka : r) (StaticRep Amazonka)
forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect]).
(HasCallStack, DispatchOf e ~ 'Static sideEffects, e :> es) =>
Eff es (StaticRep e)
getStaticRep

  Eff r a -> Eff (Amazonka : r) a
forall (es :: [Effect]) a (e :: Effect). Eff es a -> Eff (e : es) a
raise (Eff r a -> Eff (Amazonka : r) a)
-> Eff r a -> Eff (Amazonka : r) a
forall a b. (a -> b) -> a -> b
$ AwsEnv -> Eff (Amazonka : r) a -> Eff r a
forall a (r :: [Effect]).
(r <: IOE) =>
AwsEnv -> Eff (Amazonka : r) a -> Eff r a
runAmazonka (AwsEnv -> AwsEnv
f AwsEnv
awsEnv) Eff (Amazonka : r) a
m

localAmazonka :: ()
  => HasCallStack
  => r <: Amazonka
  => (AwsEnv -> AwsEnv)
  -> Eff r a
  -> Eff r a
localAmazonka :: forall (r :: [Effect]) a.
(HasCallStack, r <: Amazonka) =>
(AwsEnv -> AwsEnv) -> Eff r a -> Eff r a
localAmazonka AwsEnv -> AwsEnv
f =
  (StaticRep Amazonka -> StaticRep Amazonka) -> Eff r a -> Eff r a
forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect])
       a.
(HasCallStack, DispatchOf e ~ 'Static sideEffects, e :> es) =>
(StaticRep e -> StaticRep e) -> Eff es a -> Eff es a
localStaticRep ((StaticRep Amazonka -> StaticRep Amazonka) -> Eff r a -> Eff r a)
-> (StaticRep Amazonka -> StaticRep Amazonka) -> Eff r a -> Eff r a
forall a b. (a -> b) -> a -> b
$ \(Amazonka AwsEnv
r) -> AwsEnv -> StaticRep Amazonka
Amazonka (AwsEnv -> AwsEnv
f AwsEnv
r)

askAwsEnv :: forall r. ()
  => r <: Amazonka
  => Eff r AwsEnv
askAwsEnv :: forall (r :: [Effect]). (r <: Amazonka) => Eff r AwsEnv
askAwsEnv = do
  Amazonka AwsEnv
awsEnv <- Eff r (StaticRep Amazonka)
forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect]).
(HasCallStack, DispatchOf e ~ 'Static sideEffects, e :> es) =>
Eff es (StaticRep e)
getStaticRep

  AwsEnv -> Eff r AwsEnv
forall a. a -> Eff r a
forall (f :: * -> *) a. Applicative f => a -> f a
pure AwsEnv
awsEnv

sendAws :: forall a r. ()
  => HasCallStack
  => AwsRequest a
  => r <: Amazonka
  => r <: DataLog AwsLogEntry
  => r <: Error AwsError
  => r <: IOE
  => Typeable (AwsResponse a)
  => Typeable a
  => a
  -> Eff r (AwsResponse a)
sendAws :: forall a (r :: [Effect]).
(HasCallStack, AwsRequest a, r <: Amazonka,
 r <: DataLog AwsLogEntry, r <: Error AwsError, r <: IOE,
 Typeable (AwsResponse a), Typeable a) =>
a -> Eff r (AwsResponse a)
sendAws a
req = (HasCallStack => Eff r (AwsResponse a)) -> Eff r (AwsResponse a)
forall a. HasCallStack => (HasCallStack => a) -> a
GHC.withFrozenCallStack ((HasCallStack => Eff r (AwsResponse a)) -> Eff r (AwsResponse a))
-> (HasCallStack => Eff r (AwsResponse a)) -> Eff r (AwsResponse a)
forall a b. (a -> b) -> a -> b
$ do
  AwsEnv
envAws0 <- Eff r AwsEnv
forall (r :: [Effect]). (r <: Amazonka) => Eff r AwsEnv
askAwsEnv

  AwsEnv
envAws1 <- UnliftStrategy
-> ((forall {r}. Eff r r -> IO r) -> IO AwsEnv) -> Eff r AwsEnv
forall (es :: [Effect]) a.
(HasCallStack, IOE :> es) =>
UnliftStrategy
-> ((forall r. Eff es r -> IO r) -> IO a) -> Eff es a
withEffToIO (Persistence -> Limit -> UnliftStrategy
ConcUnlift Persistence
Persistent Limit
Unlimited) (((forall {r}. Eff r r -> IO r) -> IO AwsEnv) -> Eff r AwsEnv)
-> ((forall {r}. Eff r r -> IO r) -> IO AwsEnv) -> Eff r AwsEnv
forall a b. (a -> b) -> a -> b
$ \forall {r}. Eff r r -> IO r
effToIO ->
    AwsEnv -> IO AwsEnv
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AwsEnv -> IO AwsEnv) -> AwsEnv -> IO AwsEnv
forall a b. (a -> b) -> a -> b
$ AwsEnv
envAws0
      { AWS.logger = \LogLevel
logLevel ByteStringBuilder
builder ->
          Eff r () -> IO ()
forall {r}. Eff r r -> IO r
effToIO (Eff r () -> IO ()) -> Eff r () -> IO ()
forall a b. (a -> b) -> a -> b
$ AwsLogEntry -> Eff r ()
forall (r :: [Effect]) i.
(HasCallStack, r <: DataLog i) =>
i -> Eff r ()
dataLog (AwsLogEntry -> Eff r ()) -> AwsLogEntry -> Eff r ()
forall a b. (a -> b) -> a -> b
$ CallStack -> LogLevel -> ByteStringBuilder -> AwsLogEntry
AwsLogEntry CallStack
HasCallStack => CallStack
GHC.callStack LogLevel
logLevel ByteStringBuilder
builder
      }

  IO (Either AwsError (AwsResponse a))
-> Eff r (Either AwsError (AwsResponse a))
forall a. IO a -> Eff r a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (ResourceT IO (Either AwsError (AwsResponse a))
-> IO (Either AwsError (AwsResponse a))
forall (m :: * -> *) a. MonadUnliftIO m => ResourceT m a -> m a
runResourceT (ResourceT IO (Either AwsError (AwsResponse a))
 -> IO (Either AwsError (AwsResponse a)))
-> ResourceT IO (Either AwsError (AwsResponse a))
-> IO (Either AwsError (AwsResponse a))
forall a b. (a -> b) -> a -> b
$ AwsEnv -> a -> ResourceT IO (Either AwsError (AwsResponse a))
forall (m :: * -> *) a.
(MonadResource m, AWSRequest a, Typeable a,
 Typeable (AWSResponse a)) =>
AwsEnv -> a -> m (Either AwsError (AWSResponse a))
AWS.sendEither AwsEnv
envAws1 a
req)
    Eff r (Either AwsError (AwsResponse a))
-> (Eff r (Either AwsError (AwsResponse a))
    -> Eff r (AwsResponse a))
-> Eff r (AwsResponse a)
forall a b. a -> (a -> b) -> b
& (AwsError -> Eff r (AwsResponse a))
-> Eff r (Either AwsError (AwsResponse a)) -> Eff r (AwsResponse a)
forall e a (m :: * -> *).
Monad m =>
(e -> m a) -> m (Either e a) -> m a
onLeftM AwsError -> Eff r (AwsResponse a)
forall e (es :: [Effect]) a.
(HasCallStack, Error e :> es, Show e) =>
e -> Eff es a
throwError

lazySendAws :: forall a r. ()
  => HasCallStack
  => AwsRequest a
  => r <: DataLog AwsLogEntry
  => r <: Error AwsError
  => r <: IOE
  => r <: Lazy AwsEnv
  => Typeable (AwsResponse a)
  => Typeable a
  => a
  -> Eff r (AwsResponse a)
lazySendAws :: forall a (r :: [Effect]).
(HasCallStack, AwsRequest a, r <: DataLog AwsLogEntry,
 r <: Error AwsError, r <: IOE, r <: Lazy AwsEnv,
 Typeable (AwsResponse a), Typeable a) =>
a -> Eff r (AwsResponse a)
lazySendAws a
req = (HasCallStack => Eff r (AwsResponse a)) -> Eff r (AwsResponse a)
forall a. HasCallStack => (HasCallStack => a) -> a
GHC.withFrozenCallStack ((HasCallStack => Eff r (AwsResponse a)) -> Eff r (AwsResponse a))
-> (HasCallStack => Eff r (AwsResponse a)) -> Eff r (AwsResponse a)
forall a b. (a -> b) -> a -> b
$ do
  AwsEnv
awsEnv <- Eff r AwsEnv
forall (r :: [Effect]) i. (r <: Lazy i) => Eff r i
lazyAsk
  AwsEnv
-> Eff (Amazonka : r) (AwsResponse a) -> Eff r (AwsResponse a)
forall a (r :: [Effect]).
(r <: IOE) =>
AwsEnv -> Eff (Amazonka : r) a -> Eff r a
runAmazonka AwsEnv
awsEnv (a -> Eff (Amazonka : r) (AwsResponse a)
forall a (r :: [Effect]).
(HasCallStack, AwsRequest a, r <: Amazonka,
 r <: DataLog AwsLogEntry, r <: Error AwsError, r <: IOE,
 Typeable (AwsResponse a), Typeable a) =>
a -> Eff r (AwsResponse a)
sendAws a
req)