-- | CLI parsing for CoreConfigArgs
module Shrun.Configuration.Args.Parsing.Core
  ( coreParser,
  )
where

import Options.Applicative (Parser)
import Options.Applicative qualified as OA
import Shrun.Configuration.Args.Parsing.CommandLogging qualified as CommandLogging
import Shrun.Configuration.Args.Parsing.CommonLogging qualified as CommonLogging
import Shrun.Configuration.Args.Parsing.ConsoleLogging qualified as ConsoleLogging
import Shrun.Configuration.Args.Parsing.FileLogging qualified as FileLogging
import Shrun.Configuration.Args.Parsing.Notify qualified as Notify
import Shrun.Configuration.Args.Parsing.Utils qualified as Utils
import Shrun.Configuration.Data.Core
  ( CoreConfigArgs,
    CoreConfigP
      ( MkCoreConfigP,
        commandLogging,
        commonLogging,
        consoleLogging,
        fileLogging,
        init,
        notify,
        timeout
      ),
  )
import Shrun.Configuration.Data.Core.Timeout (Timeout)
import Shrun.Configuration.Data.Core.Timeout qualified as Timeout
import Shrun.Configuration.Data.WithDisabled (WithDisabled)
import Shrun.Prelude

coreParser :: Parser CoreConfigArgs
coreParser :: Parser CoreConfigArgs
coreParser = do
  WithDisabled Text
init <- Parser (WithDisabled Text)
initParser
  WithDisabled Timeout
timeout <- Parser (WithDisabled Timeout)
timeoutParser
  CommonLoggingArgs
commonLogging <- Parser CommonLoggingArgs
CommonLogging.commonLoggingParser
  CommandLoggingArgs
commandLogging <- Parser CommandLoggingArgs
CommandLogging.commandLoggingParser
  ConsoleLoggingArgs
consoleLogging <- Parser ConsoleLoggingArgs
ConsoleLogging.consoleLoggingParser
  FileLoggingArgs
fileLogging <- Parser FileLoggingArgs
FileLogging.fileLoggingParser
  NotifyArgs
notify <- Parser NotifyArgs
Notify.notifyParser

  pure
    $ MkCoreConfigP
      { WithDisabled Timeout
ConfigPhaseMaybeF 'ConfigPhaseArgs Timeout
timeout :: ConfigPhaseMaybeF 'ConfigPhaseArgs Timeout
timeout :: WithDisabled Timeout
timeout,
        WithDisabled Text
ConfigPhaseMaybeF 'ConfigPhaseArgs Text
init :: ConfigPhaseMaybeF 'ConfigPhaseArgs Text
init :: WithDisabled Text
init,
        CommonLoggingArgs
TomlOptF 'ConfigPhaseArgs CommonLoggingArgs
commonLogging :: TomlOptF 'ConfigPhaseArgs CommonLoggingArgs
commonLogging :: CommonLoggingArgs
commonLogging,
        ConsoleLoggingArgs
TomlOptF 'ConfigPhaseArgs ConsoleLoggingArgs
consoleLogging :: TomlOptF 'ConfigPhaseArgs ConsoleLoggingArgs
consoleLogging :: ConsoleLoggingArgs
consoleLogging,
        CommandLoggingArgs
TomlOptF 'ConfigPhaseArgs CommandLoggingArgs
commandLogging :: TomlOptF 'ConfigPhaseArgs CommandLoggingArgs
commandLogging :: CommandLoggingArgs
commandLogging,
        FileLoggingArgs
ArgsOnlyDetF 'ConfigPhaseArgs FileLoggingArgs
fileLogging :: ArgsOnlyDetF 'ConfigPhaseArgs FileLoggingArgs
fileLogging :: FileLoggingArgs
fileLogging,
        NotifyArgs
ArgsOnlyDetF 'ConfigPhaseArgs NotifyArgs
notify :: ArgsOnlyDetF 'ConfigPhaseArgs NotifyArgs
notify :: NotifyArgs
notify
      }

timeoutParser :: Parser (WithDisabled Timeout)
timeoutParser :: Parser (WithDisabled Timeout)
timeoutParser = Parser (Maybe Timeout) -> String -> Parser (WithDisabled Timeout)
forall a. Parser (Maybe a) -> String -> Parser (WithDisabled a)
Utils.withDisabledParser Parser (Maybe Timeout)
mainParser String
"timeout"
  where
    mainParser :: Parser (Maybe Timeout)
mainParser =
      Parser Timeout -> Parser (Maybe Timeout)
forall (f :: Type -> Type) a. Alternative f => f a -> f (Maybe a)
OA.optional
        (Parser Timeout -> Parser (Maybe Timeout))
-> Parser Timeout -> Parser (Maybe Timeout)
forall a b. (a -> b) -> a -> b
$ ReadM Timeout -> Mod OptionFields Timeout -> Parser Timeout
forall a. ReadM a -> Mod OptionFields a -> Parser a
OA.option
          (ReadM Natural -> ReadM Text -> ReadM Timeout
forall (f :: Type -> Type).
(Alternative f, MonadFail f) =>
f Natural -> f Text -> f Timeout
Timeout.parseTimeout ReadM Natural
forall a. Read a => ReadM a
Utils.autoStripUnderscores ReadM Text
forall s. IsString s => ReadM s
OA.str)
          ( [Mod OptionFields Timeout] -> Mod OptionFields Timeout
forall a. Monoid a => [a] -> a
mconcat
              [ String -> Mod OptionFields Timeout
forall (f :: Type -> Type) a. HasName f => String -> Mod f a
OA.long String
"timeout",
                Char -> Mod OptionFields Timeout
forall (f :: Type -> Type) a. HasName f => Char -> Mod f a
OA.short Char
't',
                String -> Mod OptionFields Timeout
forall (f :: Type -> Type) a. String -> Mod f a
Utils.mkHelp String
helpTxt,
                String -> Mod OptionFields Timeout
forall (f :: Type -> Type) a. HasMetavar f => String -> Mod f a
OA.metavar String
"(NATURAL | STRING)"
              ]
          )
    helpTxt :: String
helpTxt =
      [String] -> String
forall a. Monoid a => [a] -> a
mconcat
        [ String
"Non-negative integer setting a timeout. Can either be a raw number ",
          String
"(interpreted as seconds), or a \"time string\" e.g. 1d2h3m4s or ",
          String
"2h3s. Defaults to no timeout."
        ]

initParser :: Parser (WithDisabled Text)
initParser :: Parser (WithDisabled Text)
initParser = Parser (Maybe Text) -> String -> Parser (WithDisabled Text)
forall a. Parser (Maybe a) -> String -> Parser (WithDisabled a)
Utils.withDisabledParser Parser (Maybe Text)
mainParser String
"init"
  where
    mainParser :: Parser (Maybe Text)
mainParser =
      Parser Text -> Parser (Maybe Text)
forall (f :: Type -> Type) a. Alternative f => f a -> f (Maybe a)
OA.optional
        (Parser Text -> Parser (Maybe Text))
-> Parser Text -> Parser (Maybe Text)
forall a b. (a -> b) -> a -> b
$ ReadM Text -> Mod OptionFields Text -> Parser Text
forall a. ReadM a -> Mod OptionFields a -> Parser a
OA.option ReadM Text
forall s. IsString s => ReadM s
OA.str
        (Mod OptionFields Text -> Parser Text)
-> Mod OptionFields Text -> Parser Text
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields Text] -> Mod OptionFields Text
forall a. Monoid a => [a] -> a
mconcat
          [ String -> Mod OptionFields Text
forall (f :: Type -> Type) a. HasName f => String -> Mod f a
OA.long String
"init",
            Char -> Mod OptionFields Text
forall (f :: Type -> Type) a. HasName f => Char -> Mod f a
OA.short Char
'i',
            String -> Mod OptionFields Text
forall (f :: Type -> Type) a. String -> Mod f a
Utils.mkHelp String
helpTxt,
            String -> Mod OptionFields Text
forall (f :: Type -> Type) a. HasMetavar f => String -> Mod f a
OA.metavar String
"STRING"
          ]
    helpTxt :: String
helpTxt =
      [String] -> String
forall a. Monoid a => [a] -> a
mconcat
        [ String
"If given, init is run before each command. That is, ",
          String
"'shrun --init \". ~/.bashrc\" foo bar' is equivalent ",
          String
"to 'shrun \". ~/.bashrc && foo\" \". ~/.bashrc && bar\"'."
        ]