{- |
  This module takes care of launching the Legion runtime system and associated
  admin tools. It mainly exists to avoid a module dependency cycle between the
  runtime stuff and the admin stuff.
-}
module Network.Legion.Launch (
  forkLegionary
) where

import Control.Monad.Logger (MonadLoggerIO)
import Network.Legion.Admin (forkAdmin)
import Network.Legion.Application (LegionConstraints, Persistence)
import Network.Legion.Runtime (forkRuntime, Runtime)
import Network.Legion.Runtime.State (StartupMode)
import Network.Legion.Settings (RuntimeSettings)

{- |
  Forks the legion framework in a background thread, and returns a handle
  on the runtime environment, which can be used to make user requests.

  - @__e__@ is the type of request your application will handle. @__e__@ stands
    for __"event"__.
  - @__o__@ is the type of response produced by your application. @__o__@ stands
    for __"output"__
  - @__s__@ is the type of state maintained by your application. More
    precisely, it is the type of the individual partitions that make up
    your global application state. @__s__@ stands for __"state"__.
-}
forkLegionary :: (LegionConstraints e o s, MonadLoggerIO m)
  => Persistence e o s
    {- ^ The persistence layer used to back the legion framework. -}
  -> RuntimeSettings
    {- ^ Settings and configuration of the legion framework. -}
  -> StartupMode
  -> m (Runtime e o s)
forkLegionary persistence settings startupMode = do
  runtime <- forkRuntime persistence settings startupMode
  forkAdmin settings runtime
  return runtime