{-# OPTIONS_GHC -fno-warn-orphans #-}

module Effectful.Zoo.Amazonka.Dynamic
  ( Amazonka(..),

    runAmazonka,
    runAmazonkaM,
  ) where

import Amazonka qualified as AWS
import Effectful
import Effectful.Dispatch.Dynamic
import Effectful.Resource
import Effectful.Zoo.Amazonka.Data.AwsEnv
import Effectful.Zoo.Amazonka.Data.AwsError
import Effectful.Zoo.Amazonka.Data.AwsRequest
import Effectful.Zoo.Amazonka.Data.AwsResponse
import Effectful.Zoo.Amazonka.Static qualified as S
import Effectful.Zoo.Core
import HaskellWorks.Prelude

data Amazonka :: Effect where
  AskAwsEnv
      :: Amazonka m AwsEnv

  LocalAwsEnv
    :: (AwsEnv -> AwsEnv)
    -> m a
    -> Amazonka m a
    
  SendAws
    :: ( HasCallStack
       , AwsRequest a
       , Typeable a
       , Typeable (AwsResponse a)
       )
    => a
    -> Amazonka m (Either AwsError (AwsResponse a))
  
type instance DispatchOf Amazonka = Dynamic

runAmazonka :: forall a r. ()
  => r <: IOE
  => r <: Resource
  => AwsEnv
  -> Eff (Amazonka : r) a
  -> Eff r a
runAmazonka :: forall a (r :: [Effect]).
(r <: IOE, r <: Resource) =>
AwsEnv -> Eff (Amazonka : r) a -> Eff r a
runAmazonka AwsEnv
awsEnv =
  (Eff (Amazonka : r) a -> Eff r a)
-> (forall {a} {localEs :: [Effect]}.
    (HasCallStack, Amazonka :> localEs) =>
    LocalEnv localEs (Amazonka : r)
    -> Amazonka (Eff localEs) a -> Eff (Amazonka : r) a)
-> Eff (Amazonka : r) a
-> Eff r a
forall (e :: Effect) (handlerEs :: [Effect]) a (es :: [Effect]) b.
(HasCallStack, DispatchOf e ~ 'Dynamic) =>
(Eff handlerEs a -> Eff es b)
-> EffectHandler e handlerEs -> Eff (e : es) a -> Eff es b
reinterpret (AwsEnv -> Eff (Amazonka : r) a -> Eff r a
forall a (r :: [Effect]).
(r <: IOE) =>
AwsEnv -> Eff (Amazonka : r) a -> Eff r a
S.runAmazonka AwsEnv
awsEnv) ((forall {a} {localEs :: [Effect]}.
  (HasCallStack, Amazonka :> localEs) =>
  LocalEnv localEs (Amazonka : r)
  -> Amazonka (Eff localEs) a -> Eff (Amazonka : r) a)
 -> Eff (Amazonka : r) a -> Eff r a)
-> (forall {a} {localEs :: [Effect]}.
    (HasCallStack, Amazonka :> localEs) =>
    LocalEnv localEs (Amazonka : r)
    -> Amazonka (Eff localEs) a -> Eff (Amazonka : r) a)
-> Eff (Amazonka : r) a
-> Eff r a
forall a b. (a -> b) -> a -> b
$ \LocalEnv localEs (Amazonka : r)
env -> \case
    Amazonka (Eff localEs) a
AskAwsEnv -> Eff (Amazonka : r) a
Eff (Amazonka : r) AwsEnv
forall (r :: [Effect]). (r <: Amazonka) => Eff r AwsEnv
S.askAwsEnv
    LocalAwsEnv AwsEnv -> AwsEnv
f Eff localEs a
m -> do
      LocalEnv localEs (Amazonka : r)
-> ((forall r. Eff localEs r -> Eff (Amazonka : r) r)
    -> Eff (Amazonka : r) a)
-> Eff (Amazonka : r) a
forall (es :: [Effect]) (handlerEs :: [Effect])
       (localEs :: [Effect]) a.
(HasCallStack, SharedSuffix es handlerEs) =>
LocalEnv localEs handlerEs
-> ((forall r. Eff localEs r -> Eff es r) -> Eff es a) -> Eff es a
localSeqUnlift LocalEnv localEs (Amazonka : r)
env \forall r. Eff localEs r -> Eff (Amazonka : r) r
unlift -> (AwsEnv -> AwsEnv) -> Eff (Amazonka : r) a -> Eff (Amazonka : r) a
forall (r :: [Effect]) a.
(HasCallStack, r <: Amazonka) =>
(AwsEnv -> AwsEnv) -> Eff r a -> Eff r a
S.localAmazonka AwsEnv -> AwsEnv
f (Eff localEs a -> Eff (Amazonka : r) a
forall r. Eff localEs r -> Eff (Amazonka : r) r
unlift Eff localEs a
m)
    SendAws a
req -> do
      AwsEnv
awsEnv' <- Eff (Amazonka : r) AwsEnv
forall (r :: [Effect]). (r <: Amazonka) => Eff r AwsEnv
S.askAwsEnv
      AwsEnv -> a -> Eff (Amazonka : r) (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
awsEnv' a
req

runAmazonkaM :: forall a r. ()
  => r <: IOE
  => r <: Resource
  => Eff r AwsEnv
  -> Eff (Amazonka : r) a
  -> Eff r a
runAmazonkaM :: forall a (r :: [Effect]).
(r <: IOE, r <: Resource) =>
Eff r AwsEnv -> Eff (Amazonka : r) a -> Eff r a
runAmazonkaM Eff r AwsEnv
mk Eff (Amazonka : r) a
f = do
  AwsEnv
awsEnv <- Eff r AwsEnv
mk
  AwsEnv -> Eff (Amazonka : r) a -> Eff r a
forall a (r :: [Effect]).
(r <: IOE, r <: Resource) =>
AwsEnv -> Eff (Amazonka : r) a -> Eff r a
runAmazonka AwsEnv
awsEnv Eff (Amazonka : r) a
f