module Ribosome.Host.Run where

import Conc (ChanConsumer, ChanEvents, interpretAtomic, interpretEventsChan)
import Polysemy.Process (Process)

import Ribosome.Host.Data.Event (Event)
import Ribosome.Host.Data.HostConfig (LogConfig)
import Ribosome.Host.Data.Report (LogReport)
import Ribosome.Host.Data.Request (RequestId)
import Ribosome.Host.Data.Response (Response)
import Ribosome.Host.Data.RpcError (RpcError)
import Ribosome.Host.Data.RpcMessage (RpcMessage)
import Ribosome.Host.Effect.Reports (Reports)
import Ribosome.Host.Effect.Responses (Responses)
import Ribosome.Host.Effect.Rpc (Rpc)
import Ribosome.Host.Effect.UserError (UserError)
import Ribosome.Host.IOStack (IOStack)
import Ribosome.Host.Interpreter.Log (interpretDataLogRpc, interpretLogRpc)
import Ribosome.Host.Interpreter.Reports (interpretReports)
import Ribosome.Host.Interpreter.Responses (interpretResponses)
import Ribosome.Host.Interpreter.Rpc (interpretRpc)

type RpcProcess =
  Process RpcMessage (Either Text RpcMessage)

type RpcStack =
  [
    Log,
    DataLog LogReport,
    Rpc !! RpcError,
    Responses RequestId Response !! RpcError,
    ChanEvents Event,
    ChanConsumer Event,
    Reports
  ]

type RpcDeps =
  [
    RpcProcess,
    UserError
  ]

interpretRpcStack ::
  Members IOStack r =>
  Members RpcDeps r =>
  Members [Log, Reader LogConfig] r =>
  InterpretersFor RpcStack r
interpretRpcStack :: forall (r :: EffectRow).
(Members IOStack r, Members RpcDeps r,
 Members '[Log, Reader LogConfig] r) =>
InterpretersFor RpcStack r
interpretRpcStack =
  Sem (Reports : r) a -> Sem r a
forall (r :: EffectRow).
Members '[ChronosTime, Embed IO] r =>
InterpreterFor Reports r
interpretReports (Sem (Reports : r) a -> Sem r a)
-> (Sem
      (Log
         : DataLog LogReport : (Rpc !! RpcError)
         : (Responses RequestId Response !! RpcError)
         : Events (OutChan Event) Event
         : PScoped () (EventChan Event) (Consume Event) : Reports : r)
      a
    -> Sem (Reports : r) a)
-> Sem
     (Log
        : DataLog LogReport : (Rpc !! RpcError)
        : (Responses RequestId Response !! RpcError)
        : Events (OutChan Event) Event
        : PScoped () (EventChan Event) (Consume Event) : Reports : r)
     a
-> Sem r a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  forall e (r :: EffectRow).
Members '[Resource, Race, Async, Embed IO] r =>
InterpretersFor '[Events (OutChan e) e, ChanConsumer e] r
interpretEventsChan @Event (Sem
   (Events (OutChan Event) Event
      : PScoped () (EventChan Event) (Consume Event) : Reports : r)
   a
 -> Sem (Reports : r) a)
-> (Sem
      (Log
         : DataLog LogReport : (Rpc !! RpcError)
         : (Responses RequestId Response !! RpcError)
         : Events (OutChan Event) Event
         : PScoped () (EventChan Event) (Consume Event) : Reports : r)
      a
    -> Sem
         (Events (OutChan Event) Event
            : PScoped () (EventChan Event) (Consume Event) : Reports : r)
         a)
-> Sem
     (Log
        : DataLog LogReport : (Rpc !! RpcError)
        : (Responses RequestId Response !! RpcError)
        : Events (OutChan Event) Event
        : PScoped () (EventChan Event) (Consume Event) : Reports : r)
     a
-> Sem (Reports : r) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  Sem
  ((Responses RequestId Response !! RpcError)
     : Events (OutChan Event) Event
     : PScoped () (EventChan Event) (Consume Event) : Reports : r)
  a
-> Sem
     (Events (OutChan Event) Event
        : PScoped () (EventChan Event) (Consume Event) : Reports : r)
     a
forall k v (r :: EffectRow).
(Ord k, Num k, Show k, Member (Embed IO) r) =>
InterpreterFor (Responses k v !! RpcError) r
interpretResponses (Sem
   ((Responses RequestId Response !! RpcError)
      : Events (OutChan Event) Event
      : PScoped () (EventChan Event) (Consume Event) : Reports : r)
   a
 -> Sem
      (Events (OutChan Event) Event
         : PScoped () (EventChan Event) (Consume Event) : Reports : r)
      a)
-> (Sem
      (Log
         : DataLog LogReport : (Rpc !! RpcError)
         : (Responses RequestId Response !! RpcError)
         : Events (OutChan Event) Event
         : PScoped () (EventChan Event) (Consume Event) : Reports : r)
      a
    -> Sem
         ((Responses RequestId Response !! RpcError)
            : Events (OutChan Event) Event
            : PScoped () (EventChan Event) (Consume Event) : Reports : r)
         a)
-> Sem
     (Log
        : DataLog LogReport : (Rpc !! RpcError)
        : (Responses RequestId Response !! RpcError)
        : Events (OutChan Event) Event
        : PScoped () (EventChan Event) (Consume Event) : Reports : r)
     a
-> Sem
     (Events (OutChan Event) Event
        : PScoped () (EventChan Event) (Consume Event) : Reports : r)
     a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  Maybe ChannelId
-> InterpreterFor
     (AtomicState (Maybe ChannelId))
     ((Responses RequestId Response !! RpcError)
        : Events (OutChan Event) Event
        : PScoped () (EventChan Event) (Consume Event) : Reports : r)
forall a (r :: EffectRow).
Member (Embed IO) r =>
a -> InterpreterFor (AtomicState a) r
interpretAtomic Maybe ChannelId
forall a. Maybe a
Nothing (Sem
   (AtomicState (Maybe ChannelId)
      : (Responses RequestId Response !! RpcError)
      : Events (OutChan Event) Event
      : PScoped () (EventChan Event) (Consume Event) : Reports : r)
   a
 -> Sem
      ((Responses RequestId Response !! RpcError)
         : Events (OutChan Event) Event
         : PScoped () (EventChan Event) (Consume Event) : Reports : r)
      a)
-> (Sem
      (Log
         : DataLog LogReport : (Rpc !! RpcError)
         : (Responses RequestId Response !! RpcError)
         : Events (OutChan Event) Event
         : PScoped () (EventChan Event) (Consume Event) : Reports : r)
      a
    -> Sem
         (AtomicState (Maybe ChannelId)
            : (Responses RequestId Response !! RpcError)
            : Events (OutChan Event) Event
            : PScoped () (EventChan Event) (Consume Event) : Reports : r)
         a)
-> Sem
     (Log
        : DataLog LogReport : (Rpc !! RpcError)
        : (Responses RequestId Response !! RpcError)
        : Events (OutChan Event) Event
        : PScoped () (EventChan Event) (Consume Event) : Reports : r)
     a
-> Sem
     ((Responses RequestId Response !! RpcError)
        : Events (OutChan Event) Event
        : PScoped () (EventChan Event) (Consume Event) : Reports : r)
     a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  Sem
  ((Rpc !! RpcError)
     : AtomicState (Maybe ChannelId)
     : (Responses RequestId Response !! RpcError)
     : Events (OutChan Event) Event
     : PScoped () (EventChan Event) (Consume Event) : Reports : r)
  a
-> Sem
     (AtomicState (Maybe ChannelId)
        : (Responses RequestId Response !! RpcError)
        : Events (OutChan Event) Event
        : PScoped () (EventChan Event) (Consume Event) : Reports : r)
     a
forall o (r :: EffectRow).
(Member (AtomicState (Maybe ChannelId)) r,
 Members
   '[Responses RequestId Response !! RpcError, Process RpcMessage o,
     Log, Async]
   r) =>
InterpreterFor (Rpc !! RpcError) r
interpretRpc (Sem
   ((Rpc !! RpcError)
      : AtomicState (Maybe ChannelId)
      : (Responses RequestId Response !! RpcError)
      : Events (OutChan Event) Event
      : PScoped () (EventChan Event) (Consume Event) : Reports : r)
   a
 -> Sem
      (AtomicState (Maybe ChannelId)
         : (Responses RequestId Response !! RpcError)
         : Events (OutChan Event) Event
         : PScoped () (EventChan Event) (Consume Event) : Reports : r)
      a)
-> (Sem
      (Log
         : DataLog LogReport : (Rpc !! RpcError)
         : (Responses RequestId Response !! RpcError)
         : Events (OutChan Event) Event
         : PScoped () (EventChan Event) (Consume Event) : Reports : r)
      a
    -> Sem
         ((Rpc !! RpcError)
            : AtomicState (Maybe ChannelId)
            : (Responses RequestId Response !! RpcError)
            : Events (OutChan Event) Event
            : PScoped () (EventChan Event) (Consume Event) : Reports : r)
         a)
-> Sem
     (Log
        : DataLog LogReport : (Rpc !! RpcError)
        : (Responses RequestId Response !! RpcError)
        : Events (OutChan Event) Event
        : PScoped () (EventChan Event) (Consume Event) : Reports : r)
     a
-> Sem
     (AtomicState (Maybe ChannelId)
        : (Responses RequestId Response !! RpcError)
        : Events (OutChan Event) Event
        : PScoped () (EventChan Event) (Consume Event) : Reports : r)
     a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  Sem
  ((Rpc !! RpcError)
     : (Responses RequestId Response !! RpcError)
     : Events (OutChan Event) Event
     : PScoped () (EventChan Event) (Consume Event) : Reports : r)
  a
-> Sem
     ((Rpc !! RpcError)
        : AtomicState (Maybe ChannelId)
        : (Responses RequestId Response !! RpcError)
        : Events (OutChan Event) Event
        : PScoped () (EventChan Event) (Consume Event) : Reports : r)
     a
forall (e2 :: (* -> *) -> * -> *) (e1 :: (* -> *) -> * -> *)
       (r :: EffectRow) a.
Sem (e1 : r) a -> Sem (e1 : e2 : r) a
raiseUnder (Sem
   ((Rpc !! RpcError)
      : (Responses RequestId Response !! RpcError)
      : Events (OutChan Event) Event
      : PScoped () (EventChan Event) (Consume Event) : Reports : r)
   a
 -> Sem
      ((Rpc !! RpcError)
         : AtomicState (Maybe ChannelId)
         : (Responses RequestId Response !! RpcError)
         : Events (OutChan Event) Event
         : PScoped () (EventChan Event) (Consume Event) : Reports : r)
      a)
-> (Sem
      (Log
         : DataLog LogReport : (Rpc !! RpcError)
         : (Responses RequestId Response !! RpcError)
         : Events (OutChan Event) Event
         : PScoped () (EventChan Event) (Consume Event) : Reports : r)
      a
    -> Sem
         ((Rpc !! RpcError)
            : (Responses RequestId Response !! RpcError)
            : Events (OutChan Event) Event
            : PScoped () (EventChan Event) (Consume Event) : Reports : r)
         a)
-> Sem
     (Log
        : DataLog LogReport : (Rpc !! RpcError)
        : (Responses RequestId Response !! RpcError)
        : Events (OutChan Event) Event
        : PScoped () (EventChan Event) (Consume Event) : Reports : r)
     a
-> Sem
     ((Rpc !! RpcError)
        : AtomicState (Maybe ChannelId)
        : (Responses RequestId Response !! RpcError)
        : Events (OutChan Event) Event
        : PScoped () (EventChan Event) (Consume Event) : Reports : r)
     a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  Sem
  (DataLog LogReport
     : (Rpc !! RpcError) : (Responses RequestId Response !! RpcError)
     : Events (OutChan Event) Event
     : PScoped () (EventChan Event) (Consume Event) : Reports : r)
  a
-> Sem
     ((Rpc !! RpcError)
        : (Responses RequestId Response !! RpcError)
        : Events (OutChan Event) Event
        : PScoped () (EventChan Event) (Consume Event) : Reports : r)
     a
forall e (r :: EffectRow).
(Show e,
 Members
   '[Reader LogConfig, Rpc !! e, Reports, UserError, Log, Resource,
     Race, Async, Embed IO]
   r) =>
InterpreterFor (DataLog LogReport) r
interpretDataLogRpc (Sem
   (DataLog LogReport
      : (Rpc !! RpcError) : (Responses RequestId Response !! RpcError)
      : Events (OutChan Event) Event
      : PScoped () (EventChan Event) (Consume Event) : Reports : r)
   a
 -> Sem
      ((Rpc !! RpcError)
         : (Responses RequestId Response !! RpcError)
         : Events (OutChan Event) Event
         : PScoped () (EventChan Event) (Consume Event) : Reports : r)
      a)
-> (Sem
      (Log
         : DataLog LogReport : (Rpc !! RpcError)
         : (Responses RequestId Response !! RpcError)
         : Events (OutChan Event) Event
         : PScoped () (EventChan Event) (Consume Event) : Reports : r)
      a
    -> Sem
         (DataLog LogReport
            : (Rpc !! RpcError) : (Responses RequestId Response !! RpcError)
            : Events (OutChan Event) Event
            : PScoped () (EventChan Event) (Consume Event) : Reports : r)
         a)
-> Sem
     (Log
        : DataLog LogReport : (Rpc !! RpcError)
        : (Responses RequestId Response !! RpcError)
        : Events (OutChan Event) Event
        : PScoped () (EventChan Event) (Consume Event) : Reports : r)
     a
-> Sem
     ((Rpc !! RpcError)
        : (Responses RequestId Response !! RpcError)
        : Events (OutChan Event) Event
        : PScoped () (EventChan Event) (Consume Event) : Reports : r)
     a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  Sem
  (Log
     : DataLog LogReport : (Rpc !! RpcError)
     : (Responses RequestId Response !! RpcError)
     : Events (OutChan Event) Event
     : PScoped () (EventChan Event) (Consume Event) : Reports : r)
  a
-> Sem
     (DataLog LogReport
        : (Rpc !! RpcError) : (Responses RequestId Response !! RpcError)
        : Events (OutChan Event) Event
        : PScoped () (EventChan Event) (Consume Event) : Reports : r)
     a
forall (r :: EffectRow).
Members '[Log, DataLog LogReport] r =>
InterpreterFor Log r
interpretLogRpc