-- |Interpreters for basic plugin effects down to 'IO'
module Ribosome.IOStack where

import Ribosome.Cli (withCli)
import Ribosome.Data.CustomConfig (CustomConfig (CustomConfig))
import Ribosome.Data.PluginConfig (PluginConfig (PluginConfig))
import Ribosome.Data.PluginName (PluginName)
import Ribosome.Host.Data.HostConfig (HostConfig)
import Ribosome.Host.IOStack (BasicStack, runBasicStack)

-- |The effects that are shared by all variants (like embedded, remote, socket) of main functions.
--
-- Contains logging effects, IO related stuff and the plugin's name in a 'Reader'.
type BasicPluginStack c =
  Reader PluginName : Reader (CustomConfig c) : BasicStack

-- |Execute the basic plugin stack all the way to an 'IO', given the plugin name and logging settings.
runBasicPluginStack ::
  PluginName ->
  HostConfig ->
  c ->
  Sem (BasicPluginStack c) () ->
  IO ()
runBasicPluginStack :: forall c.
PluginName
-> HostConfig -> c -> Sem (BasicPluginStack c) () -> IO ()
runBasicPluginStack PluginName
name HostConfig
conf c
custom =
  HostConfig
-> Sem
     (Append
        '[Log, StderrLog, FileLog, Reader LogConfig, Reader HostConfig]
        (Append '[ChronosTime, Error BootError] ConcStack))
     ()
-> IO ()
runBasicStack HostConfig
conf (Sem
   (Log
      : StderrLog : FileLog : Reader LogConfig : Reader HostConfig
      : ChronosTime : Error BootError : ConcStack)
   ()
 -> IO ())
-> (Sem
      (Reader PluginName
         : Reader (CustomConfig c) : Log : StderrLog : FileLog
         : Reader LogConfig : Reader HostConfig : ChronosTime
         : Error BootError : ConcStack)
      ()
    -> Sem
         (Log
            : StderrLog : FileLog : Reader LogConfig : Reader HostConfig
            : ChronosTime : Error BootError : ConcStack)
         ())
-> Sem
     (Reader PluginName
        : Reader (CustomConfig c) : Log : StderrLog : FileLog
        : Reader LogConfig : Reader HostConfig : ChronosTime
        : Error BootError : ConcStack)
     ()
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  CustomConfig c
-> Sem
     (Reader (CustomConfig c)
        : Log : StderrLog : FileLog : Reader LogConfig : Reader HostConfig
        : ChronosTime : Error BootError : ConcStack)
     ()
-> Sem
     (Log
        : StderrLog : FileLog : Reader LogConfig : Reader HostConfig
        : ChronosTime : Error BootError : ConcStack)
     ()
forall i (r :: [(* -> *) -> * -> *]) a.
i -> Sem (Reader i : r) a -> Sem r a
runReader (c -> CustomConfig c
forall c. c -> CustomConfig c
CustomConfig c
custom) (Sem
   (Reader (CustomConfig c)
      : Log : StderrLog : FileLog : Reader LogConfig : Reader HostConfig
      : ChronosTime : Error BootError : ConcStack)
   ()
 -> Sem
      (Log
         : StderrLog : FileLog : Reader LogConfig : Reader HostConfig
         : ChronosTime : Error BootError : ConcStack)
      ())
-> (Sem
      (Reader PluginName
         : Reader (CustomConfig c) : Log : StderrLog : FileLog
         : Reader LogConfig : Reader HostConfig : ChronosTime
         : Error BootError : ConcStack)
      ()
    -> Sem
         (Reader (CustomConfig c)
            : Log : StderrLog : FileLog : Reader LogConfig : Reader HostConfig
            : ChronosTime : Error BootError : ConcStack)
         ())
-> Sem
     (Reader PluginName
        : Reader (CustomConfig c) : Log : StderrLog : FileLog
        : Reader LogConfig : Reader HostConfig : ChronosTime
        : Error BootError : ConcStack)
     ()
-> Sem
     (Log
        : StderrLog : FileLog : Reader LogConfig : Reader HostConfig
        : ChronosTime : Error BootError : ConcStack)
     ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  PluginName
-> Sem
     (Reader PluginName
        : Reader (CustomConfig c) : Log : StderrLog : FileLog
        : Reader LogConfig : Reader HostConfig : ChronosTime
        : Error BootError : ConcStack)
     ()
-> Sem
     (Reader (CustomConfig c)
        : Log : StderrLog : FileLog : Reader LogConfig : Reader HostConfig
        : ChronosTime : Error BootError : ConcStack)
     ()
forall i (r :: [(* -> *) -> * -> *]) a.
i -> Sem (Reader i : r) a -> Sem r a
runReader PluginName
name

-- |Execute the basic plugin stack all the way to an 'IO' like 'runBasicPluginStack', reading config overrides from
-- command line options.
runCli ::
  PluginConfig c ->
  Sem (BasicPluginStack c) () ->
  IO ()
runCli :: forall c. PluginConfig c -> Sem (BasicPluginStack c) () -> IO ()
runCli (PluginConfig PluginName
name HostConfig
defaultConf Parser c
customParser) Sem (BasicPluginStack c) ()
prog =
  PluginName
-> HostConfig -> Parser c -> (HostConfig -> c -> IO ()) -> IO ()
forall c a.
PluginName
-> HostConfig -> Parser c -> (HostConfig -> c -> IO a) -> IO a
withCli PluginName
name HostConfig
defaultConf Parser c
customParser \ HostConfig
conf c
custom ->
    PluginName
-> HostConfig -> c -> Sem (BasicPluginStack c) () -> IO ()
forall c.
PluginName
-> HostConfig -> c -> Sem (BasicPluginStack c) () -> IO ()
runBasicPluginStack PluginName
name HostConfig
conf c
custom Sem (BasicPluginStack c) ()
prog