module Ribosome.App.Cli where

import Polysemy.Chronos (ChronosTime, interpretTimeChronos)
import System.Exit (exitFailure)
import System.IO (stderr)

import Ribosome.App.Boot (generateBoot)
import Ribosome.App.Data (Global (Global))
import Ribosome.App.Error (RainbowError, runRainbowErrorAnd)
import Ribosome.App.NewOptions (newOptions)
import Ribosome.App.NewProject (newProject)
import Ribosome.App.Options (Command (Boot, New), GlobalOptions (GlobalOptions), Options (..), parseCli)
import Ribosome.App.ProjectOptions (projectOptions)

runCommand ::
  Members [ChronosTime, Stop RainbowError, Embed IO] r =>
  Global ->
  Command ->
  Sem r ()
runCommand :: forall (r :: [(* -> *) -> * -> *]).
Members '[ChronosTime, Stop RainbowError, Embed IO] r =>
Global -> Command -> Sem r ()
runCommand Global
global = \case
  New NewOptions
opts -> do
    NewProject
conf <- NewOptions -> Sem r NewProject
forall (r :: [(* -> *) -> * -> *]).
Members '[Stop RainbowError, Embed IO] r =>
NewOptions -> Sem r NewProject
newOptions NewOptions
opts
    Global -> NewProject -> Sem r ()
forall (r :: [(* -> *) -> * -> *]).
Members '[ChronosTime, Stop RainbowError, Embed IO] r =>
Global -> NewProject -> Sem r ()
newProject Global
global NewProject
conf
  Boot ProjectOptions
opts -> do
    Project
conf <- Bool -> ProjectOptions -> Sem r Project
forall (r :: [(* -> *) -> * -> *]).
Members '[Stop RainbowError, Embed IO] r =>
Bool -> ProjectOptions -> Sem r Project
projectOptions Bool
False ProjectOptions
opts
    Global -> Project -> Sem r ()
forall (r :: [(* -> *) -> * -> *]).
Members '[Stop RainbowError, Embed IO] r =>
Global -> Project -> Sem r ()
generateBoot Global
global Project
conf

runOptions ::
  Members [ChronosTime, Stop RainbowError, Embed IO] r =>
  Options ->
  Sem r ()
runOptions :: forall (r :: [(* -> *) -> * -> *]).
Members '[ChronosTime, Stop RainbowError, Embed IO] r =>
Options -> Sem r ()
runOptions (Options (GlobalOptions Maybe Bool
quiet Maybe Bool
force) Command
cmd) =
  Global -> Command -> Sem r ()
forall (r :: [(* -> *) -> * -> *]).
Members '[ChronosTime, Stop RainbowError, Embed IO] r =>
Global -> Command -> Sem r ()
runCommand (Bool -> Bool -> Global
Global (Bool -> Maybe Bool -> Bool
forall a. a -> Maybe a -> a
fromMaybe Bool
False Maybe Bool
quiet) (Bool -> Maybe Bool -> Bool
forall a. a -> Maybe a -> a
fromMaybe Bool
False Maybe Bool
force)) Command
cmd

main :: IO ()
main :: IO ()
main = do
  Options
conf <- IO Options
parseCli
  Sem ConcStack () -> IO ()
forall a. Sem ConcStack a -> IO a
runConc (Sem ConcStack () -> IO ()) -> Sem ConcStack () -> IO ()
forall a b. (a -> b) -> a -> b
$ Sem (ChronosTime : ConcStack) () -> Sem ConcStack ()
forall (r :: [(* -> *) -> * -> *]).
Member (Embed IO) r =>
InterpreterFor ChronosTime r
interpretTimeChronos (Handle
-> Sem (ChronosTime : ConcStack) ()
-> Sem (Stop RainbowError : ChronosTime : ConcStack) ()
-> Sem (ChronosTime : ConcStack) ()
forall (r :: [(* -> *) -> * -> *]).
Members '[Embed IO, Final IO] r =>
Handle -> Sem r () -> Sem (Stop RainbowError : r) () -> Sem r ()
runRainbowErrorAnd Handle
stderr (IO () -> Sem (ChronosTime : ConcStack) ()
forall (m :: * -> *) (r :: [(* -> *) -> * -> *]) a.
Member (Embed m) r =>
m a -> Sem r a
embed IO ()
forall a. IO a
exitFailure) (Options -> Sem (Stop RainbowError : ChronosTime : ConcStack) ()
forall (r :: [(* -> *) -> * -> *]).
Members '[ChronosTime, Stop RainbowError, Embed IO] r =>
Options -> Sem r ()
runOptions Options
conf))