{-# LANGUAGE UndecidableInstances #-}

module Mensam.Client.Application where

import Mensam.Client.Application.Event
import Mensam.Client.Application.Event.Class
import Mensam.Client.Application.HttpClient
import Mensam.Client.Application.MensamClient
import Mensam.Client.Application.MensamClient.Class
import Mensam.Client.Application.Options
import Mensam.Client.Application.Options.Class
import Mensam.Client.UI.Brick.Events (ClientEvent)

import Brick.BChan (BChan)
import Control.Monad.IO.Class
import Control.Monad.Logger.CallStack
import Control.Monad.Logger.OrphanInstances ()
import Control.Monad.Trans.Class
import Control.Monad.Trans.Compose.Stack
import Control.Monad.Trans.Control
import Control.Monad.Trans.Control.Identity
import Data.Kind

type Transformers :: Stack
type Transformers =
  NilT
    :.|> OptionsT
    :.|> NoLoggingT
    :.|> HttpClientT
    :.|> MensamClientT
    :.|> EventT

type ApplicationT :: (Type -> Type) -> Type -> Type
newtype ApplicationT m a = ApplicationT {forall (m :: * -> *) a. ApplicationT m a -> StackT Transformers m a
unApplicationT :: StackT Transformers m a}
  deriving newtype (Functor (ApplicationT m)
Functor (ApplicationT m) =>
(forall a. a -> ApplicationT m a)
-> (forall a b.
    ApplicationT m (a -> b) -> ApplicationT m a -> ApplicationT m b)
-> (forall a b c.
    (a -> b -> c)
    -> ApplicationT m a -> ApplicationT m b -> ApplicationT m c)
-> (forall a b.
    ApplicationT m a -> ApplicationT m b -> ApplicationT m b)
-> (forall a b.
    ApplicationT m a -> ApplicationT m b -> ApplicationT m a)
-> Applicative (ApplicationT m)
forall a. a -> ApplicationT m a
forall a b.
ApplicationT m a -> ApplicationT m b -> ApplicationT m a
forall a b.
ApplicationT m a -> ApplicationT m b -> ApplicationT m b
forall a b.
ApplicationT m (a -> b) -> ApplicationT m a -> ApplicationT m b
forall a b c.
(a -> b -> c)
-> ApplicationT m a -> ApplicationT m b -> ApplicationT m c
forall (f :: * -> *).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
forall (m :: * -> *). Applicative m => Functor (ApplicationT m)
forall (m :: * -> *) a. Applicative m => a -> ApplicationT m a
forall (m :: * -> *) a b.
Applicative m =>
ApplicationT m a -> ApplicationT m b -> ApplicationT m a
forall (m :: * -> *) a b.
Applicative m =>
ApplicationT m a -> ApplicationT m b -> ApplicationT m b
forall (m :: * -> *) a b.
Applicative m =>
ApplicationT m (a -> b) -> ApplicationT m a -> ApplicationT m b
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> ApplicationT m a -> ApplicationT m b -> ApplicationT m c
$cpure :: forall (m :: * -> *) a. Applicative m => a -> ApplicationT m a
pure :: forall a. a -> ApplicationT m a
$c<*> :: forall (m :: * -> *) a b.
Applicative m =>
ApplicationT m (a -> b) -> ApplicationT m a -> ApplicationT m b
<*> :: forall a b.
ApplicationT m (a -> b) -> ApplicationT m a -> ApplicationT m b
$cliftA2 :: forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> ApplicationT m a -> ApplicationT m b -> ApplicationT m c
liftA2 :: forall a b c.
(a -> b -> c)
-> ApplicationT m a -> ApplicationT m b -> ApplicationT m c
$c*> :: forall (m :: * -> *) a b.
Applicative m =>
ApplicationT m a -> ApplicationT m b -> ApplicationT m b
*> :: forall a b.
ApplicationT m a -> ApplicationT m b -> ApplicationT m b
$c<* :: forall (m :: * -> *) a b.
Applicative m =>
ApplicationT m a -> ApplicationT m b -> ApplicationT m a
<* :: forall a b.
ApplicationT m a -> ApplicationT m b -> ApplicationT m a
Applicative, (forall a b. (a -> b) -> ApplicationT m a -> ApplicationT m b)
-> (forall a b. a -> ApplicationT m b -> ApplicationT m a)
-> Functor (ApplicationT m)
forall a b. a -> ApplicationT m b -> ApplicationT m a
forall a b. (a -> b) -> ApplicationT m a -> ApplicationT m b
forall (m :: * -> *) a b.
Functor m =>
a -> ApplicationT m b -> ApplicationT m a
forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> ApplicationT m a -> ApplicationT m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> ApplicationT m a -> ApplicationT m b
fmap :: forall a b. (a -> b) -> ApplicationT m a -> ApplicationT m b
$c<$ :: forall (m :: * -> *) a b.
Functor m =>
a -> ApplicationT m b -> ApplicationT m a
<$ :: forall a b. a -> ApplicationT m b -> ApplicationT m a
Functor, Applicative (ApplicationT m)
Applicative (ApplicationT m) =>
(forall a b.
 ApplicationT m a -> (a -> ApplicationT m b) -> ApplicationT m b)
-> (forall a b.
    ApplicationT m a -> ApplicationT m b -> ApplicationT m b)
-> (forall a. a -> ApplicationT m a)
-> Monad (ApplicationT m)
forall a. a -> ApplicationT m a
forall a b.
ApplicationT m a -> ApplicationT m b -> ApplicationT m b
forall a b.
ApplicationT m a -> (a -> ApplicationT m b) -> ApplicationT m b
forall (m :: * -> *). Monad m => Applicative (ApplicationT m)
forall (m :: * -> *) a. Monad m => a -> ApplicationT m a
forall (m :: * -> *) a b.
Monad m =>
ApplicationT m a -> ApplicationT m b -> ApplicationT m b
forall (m :: * -> *) a b.
Monad m =>
ApplicationT m a -> (a -> ApplicationT m b) -> ApplicationT m b
forall (m :: * -> *).
Applicative m =>
(forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
$c>>= :: forall (m :: * -> *) a b.
Monad m =>
ApplicationT m a -> (a -> ApplicationT m b) -> ApplicationT m b
>>= :: forall a b.
ApplicationT m a -> (a -> ApplicationT m b) -> ApplicationT m b
$c>> :: forall (m :: * -> *) a b.
Monad m =>
ApplicationT m a -> ApplicationT m b -> ApplicationT m b
>> :: forall a b.
ApplicationT m a -> ApplicationT m b -> ApplicationT m b
$creturn :: forall (m :: * -> *) a. Monad m => a -> ApplicationT m a
return :: forall a. a -> ApplicationT m a
Monad)
  deriving newtype ((forall (m :: * -> *). Monad m => Monad (ApplicationT m)) =>
(forall (m :: * -> *) a. Monad m => m a -> ApplicationT m a)
-> MonadTrans ApplicationT
forall (m :: * -> *). Monad m => Monad (ApplicationT m)
forall (m :: * -> *) a. Monad m => m a -> ApplicationT m a
forall (t :: (* -> *) -> * -> *).
(forall (m :: * -> *). Monad m => Monad (t m)) =>
(forall (m :: * -> *) a. Monad m => m a -> t m a) -> MonadTrans t
$clift :: forall (m :: * -> *) a. Monad m => m a -> ApplicationT m a
lift :: forall (m :: * -> *) a. Monad m => m a -> ApplicationT m a
MonadTrans, MonadTrans ApplicationT
MonadTrans ApplicationT =>
(forall (m :: * -> *) a.
 Monad m =>
 (Run ApplicationT -> m a) -> ApplicationT m a)
-> (forall (m :: * -> *) a.
    Monad m =>
    m (StT ApplicationT a) -> ApplicationT m a)
-> MonadTransControl ApplicationT
forall (m :: * -> *) a.
Monad m =>
m (StT ApplicationT a) -> ApplicationT m a
forall (m :: * -> *) a.
Monad m =>
(Run ApplicationT -> m a) -> ApplicationT m a
forall (t :: (* -> *) -> * -> *).
MonadTrans t =>
(forall (m :: * -> *) a. Monad m => (Run t -> m a) -> t m a)
-> (forall (m :: * -> *) a. Monad m => m (StT t a) -> t m a)
-> MonadTransControl t
$cliftWith :: forall (m :: * -> *) a.
Monad m =>
(Run ApplicationT -> m a) -> ApplicationT m a
liftWith :: forall (m :: * -> *) a.
Monad m =>
(Run ApplicationT -> m a) -> ApplicationT m a
$crestoreT :: forall (m :: * -> *) a.
Monad m =>
m (StT ApplicationT a) -> ApplicationT m a
restoreT :: forall (m :: * -> *) a.
Monad m =>
m (StT ApplicationT a) -> ApplicationT m a
MonadTransControl, MonadTransControl ApplicationT
MonadTransControl ApplicationT =>
(forall (m :: * -> *) a.
 Monad m =>
 ((forall x. ApplicationT m x -> m x) -> m a) -> ApplicationT m a)
-> MonadTransControlIdentity ApplicationT
forall (m :: * -> *) a.
Monad m =>
((forall x. ApplicationT m x -> m x) -> m a) -> ApplicationT m a
forall (t :: (* -> *) -> * -> *).
MonadTransControl t =>
(forall (m :: * -> *) a.
 Monad m =>
 ((forall x. t m x -> m x) -> m a) -> t m a)
-> MonadTransControlIdentity t
$cliftWithIdentity :: forall (m :: * -> *) a.
Monad m =>
((forall x. ApplicationT m x -> m x) -> m a) -> ApplicationT m a
liftWithIdentity :: forall (m :: * -> *) a.
Monad m =>
((forall x. ApplicationT m x -> m x) -> m a) -> ApplicationT m a
MonadTransControlIdentity)
  deriving newtype (Monad (ApplicationT m)
ApplicationT m Options
Monad (ApplicationT m) =>
ApplicationT m Options -> MonadOptions (ApplicationT m)
forall (m :: * -> *). Monad m => Monad (ApplicationT m)
forall (m :: * -> *). Monad m => ApplicationT m Options
forall (m :: * -> *). Monad m => m Options -> MonadOptions m
$coptions :: forall (m :: * -> *). Monad m => ApplicationT m Options
options :: ApplicationT m Options
MonadOptions)
  deriving newtype (Monad (ApplicationT m)
Monad (ApplicationT m) =>
(forall msg.
 ToLogStr msg =>
 Loc -> LogSource -> LogLevel -> msg -> ApplicationT m ())
-> MonadLogger (ApplicationT m)
forall msg.
ToLogStr msg =>
Loc -> LogSource -> LogLevel -> msg -> ApplicationT m ()
forall (m :: * -> *). Monad m => Monad (ApplicationT m)
forall (m :: * -> *).
Monad m =>
(forall msg.
 ToLogStr msg =>
 Loc -> LogSource -> LogLevel -> msg -> m ())
-> MonadLogger m
forall (m :: * -> *) msg.
(Monad m, ToLogStr msg) =>
Loc -> LogSource -> LogLevel -> msg -> ApplicationT m ()
$cmonadLoggerLog :: forall (m :: * -> *) msg.
(Monad m, ToLogStr msg) =>
Loc -> LogSource -> LogLevel -> msg -> ApplicationT m ()
monadLoggerLog :: forall msg.
ToLogStr msg =>
Loc -> LogSource -> LogLevel -> msg -> ApplicationT m ()
MonadLogger)
  deriving newtype (Monad (ApplicationT m)
Monad (ApplicationT m) =>
(forall a. ClientM a -> ApplicationT m (Either ClientError a))
-> MonadMensamClient (ApplicationT m)
forall a. ClientM a -> ApplicationT m (Either ClientError a)
forall (m :: * -> *).
Monad m =>
(forall a. ClientM a -> m (Either ClientError a))
-> MonadMensamClient m
forall (m :: * -> *). MonadIO m => Monad (ApplicationT m)
forall (m :: * -> *) a.
MonadIO m =>
ClientM a -> ApplicationT m (Either ClientError a)
$cmensamCall :: forall (m :: * -> *) a.
MonadIO m =>
ClientM a -> ApplicationT m (Either ClientError a)
mensamCall :: forall a. ClientM a -> ApplicationT m (Either ClientError a)
MonadMensamClient)
  deriving newtype (Monad (ApplicationT m)
ApplicationT m (BChan ClientEvent)
Monad (ApplicationT m) =>
(ClientEvent -> ApplicationT m ())
-> ApplicationT m (BChan ClientEvent)
-> MonadEvent (ApplicationT m)
ClientEvent -> ApplicationT m ()
forall (m :: * -> *).
Monad m =>
(ClientEvent -> m ()) -> m (BChan ClientEvent) -> MonadEvent m
forall (m :: * -> *). MonadIO m => Monad (ApplicationT m)
forall (m :: * -> *).
MonadIO m =>
ApplicationT m (BChan ClientEvent)
forall (m :: * -> *). MonadIO m => ClientEvent -> ApplicationT m ()
$csendEvent :: forall (m :: * -> *). MonadIO m => ClientEvent -> ApplicationT m ()
sendEvent :: ClientEvent -> ApplicationT m ()
$ceventChannel :: forall (m :: * -> *).
MonadIO m =>
ApplicationT m (BChan ClientEvent)
eventChannel :: ApplicationT m (BChan ClientEvent)
MonadEvent)

runApplicationT ::
  MonadIO m =>
  BChan ClientEvent ->
  ApplicationT m a ->
  m a
runApplicationT :: forall (m :: * -> *) a.
MonadIO m =>
BChan ClientEvent -> ApplicationT m a -> m a
runApplicationT BChan ClientEvent
chan ApplicationT m a
app = do
  let
    runTransformers :: MonadIO m => RunStackT Transformers m a
    runTransformers :: forall (m :: * -> *) a. MonadIO m => RunStackT Transformers m a
runTransformers =
      RunStackT NilT m a
forall (b :: * -> *) c. RunStackT NilT b c
RunNilT
        RunStackT NilT m a
-> (OptionsT (StackT NilT m) a -> StackT NilT m a)
-> RunStackT (NilT :.|> OptionsT) m a
forall (ts :: Stack) (b :: * -> *) c (t :: (* -> *) -> * -> *).
RunStackT ts b c
-> (t (StackT ts b) c -> StackT ts b c)
-> RunStackT (ts :.|> t) b c
:..> OptionsT (Elevator NoT m) a -> Elevator NoT m a
OptionsT (StackT NilT m) a -> StackT NilT m a
forall (m :: * -> *) a. MonadIO m => OptionsT m a -> m a
runAppOptionsT
        RunStackT (NilT :.|> OptionsT) m a
-> (NoLoggingT (StackT (NilT :.|> OptionsT) m) a
    -> StackT (NilT :.|> OptionsT) m a)
-> RunStackT ((NilT :.|> OptionsT) :.|> NoLoggingT) m a
forall (ts :: Stack) (b :: * -> *) c (t :: (* -> *) -> * -> *).
RunStackT ts b c
-> (t (StackT ts b) c -> StackT ts b c)
-> RunStackT (ts :.|> t) b c
:..> NoLoggingT (ComposeT OptionsT TransparentT m) a
-> ComposeT OptionsT TransparentT m a
NoLoggingT (StackT (NilT :.|> OptionsT) m) a
-> StackT (NilT :.|> OptionsT) m a
forall (m :: * -> *) a. NoLoggingT m a -> m a
runNoLoggingT
        RunStackT ((NilT :.|> OptionsT) :.|> NoLoggingT) m a
-> (HttpClientT (StackT ((NilT :.|> OptionsT) :.|> NoLoggingT) m) a
    -> StackT ((NilT :.|> OptionsT) :.|> NoLoggingT) m a)
-> RunStackT
     (((NilT :.|> OptionsT) :.|> NoLoggingT) :.|> HttpClientT) m a
forall (ts :: Stack) (b :: * -> *) c (t :: (* -> *) -> * -> *).
RunStackT ts b c
-> (t (StackT ts b) c -> StackT ts b c)
-> RunStackT (ts :.|> t) b c
:..> HttpClientT
  (ComposeT NoLoggingT (ComposeT OptionsT TransparentT) m) a
-> ComposeT NoLoggingT (ComposeT OptionsT TransparentT) m a
HttpClientT (StackT ((NilT :.|> OptionsT) :.|> NoLoggingT) m) a
-> StackT ((NilT :.|> OptionsT) :.|> NoLoggingT) m a
forall (m :: * -> *) a.
(MonadIO m, MonadLogger m) =>
HttpClientT m a -> m a
runAppHttpClientT
        RunStackT
  (((NilT :.|> OptionsT) :.|> NoLoggingT) :.|> HttpClientT) m a
-> (MensamClientT
      (StackT
         (((NilT :.|> OptionsT) :.|> NoLoggingT) :.|> HttpClientT) m)
      a
    -> StackT
         (((NilT :.|> OptionsT) :.|> NoLoggingT) :.|> HttpClientT) m a)
-> RunStackT
     ((((NilT :.|> OptionsT) :.|> NoLoggingT) :.|> HttpClientT)
      :.|> MensamClientT)
     m
     a
forall (ts :: Stack) (b :: * -> *) c (t :: (* -> *) -> * -> *).
RunStackT ts b c
-> (t (StackT ts b) c -> StackT ts b c)
-> RunStackT (ts :.|> t) b c
:..> MensamClientT
  (ComposeT
     HttpClientT
     (ComposeT NoLoggingT (ComposeT OptionsT TransparentT))
     m)
  a
-> ComposeT
     HttpClientT
     (ComposeT NoLoggingT (ComposeT OptionsT TransparentT))
     m
     a
MensamClientT
  (StackT
     (((NilT :.|> OptionsT) :.|> NoLoggingT) :.|> HttpClientT) m)
  a
-> StackT
     (((NilT :.|> OptionsT) :.|> NoLoggingT) :.|> HttpClientT) m a
forall (m :: * -> *) a.
(MonadIO m, MonadHttpClient m, MonadLogger m, MonadOptions m) =>
MensamClientT m a -> m a
runAppMensamClientT
        RunStackT
  ((((NilT :.|> OptionsT) :.|> NoLoggingT) :.|> HttpClientT)
   :.|> MensamClientT)
  m
  a
-> (EventT
      (StackT
         ((((NilT :.|> OptionsT) :.|> NoLoggingT) :.|> HttpClientT)
          :.|> MensamClientT)
         m)
      a
    -> StackT
         ((((NilT :.|> OptionsT) :.|> NoLoggingT) :.|> HttpClientT)
          :.|> MensamClientT)
         m
         a)
-> RunStackT Transformers m a
forall (ts :: Stack) (b :: * -> *) c (t :: (* -> *) -> * -> *).
RunStackT ts b c
-> (t (StackT ts b) c -> StackT ts b c)
-> RunStackT (ts :.|> t) b c
:..> (EventT
  (StackT
     ((((NilT :.|> OptionsT) :.|> NoLoggingT) :.|> HttpClientT)
      :.|> MensamClientT)
     m)
  a
-> BChan ClientEvent
-> StackT
     ((((NilT :.|> OptionsT) :.|> NoLoggingT) :.|> HttpClientT)
      :.|> MensamClientT)
     m
     a
forall (m :: * -> *) a. EventT m a -> BChan ClientEvent -> m a
`runEventT` BChan ClientEvent
chan)

  RunStackT Transformers m a -> StackT Transformers m a -> m a
forall (ts :: Stack) (m :: * -> *) a.
RunStackT ts m a -> StackT ts m a -> m a
runStackT RunStackT Transformers m a
forall (m :: * -> *) a. MonadIO m => RunStackT Transformers m a
runTransformers (StackT Transformers m a -> m a) -> StackT Transformers m a -> m a
forall a b. (a -> b) -> a -> b
$ ApplicationT m a -> StackT Transformers m a
forall (m :: * -> *) a. ApplicationT m a -> StackT Transformers m a
unApplicationT ApplicationT m a
app