-- | CLI parsing for ConsoleLoggingArgs
module Shrun.Configuration.Args.Parsing.ConsoleLogging
  ( consoleLoggingParser,
  )
where

import Options.Applicative (Parser)
import Options.Applicative qualified as OA
import Shrun.Configuration.Args.Parsing.Utils qualified as Utils
import Shrun.Configuration.Data.ConsoleLogging
  ( ConsoleLoggingArgs,
    ConsoleLoggingP
      ( MkConsoleLoggingP,
        commandLogging,
        commandNameTrunc,
        lineTrunc,
        stripControl,
        timerFormat
      ),
  )
import Shrun.Configuration.Data.ConsoleLogging.TimerFormat (TimerFormat)
import Shrun.Configuration.Data.ConsoleLogging.TimerFormat qualified as TimerFormat
import Shrun.Configuration.Data.StripControl (ConsoleLogStripControl)
import Shrun.Configuration.Data.StripControl qualified as StripControl
import Shrun.Configuration.Data.Truncation
  ( LineTruncation,
    TruncRegion (TruncCommandName),
    Truncation,
  )
import Shrun.Configuration.Data.Truncation qualified as Trunc
import Shrun.Configuration.Data.WithDisabled (WithDisabled)
import Shrun.Prelude

consoleLoggingParser :: Parser ConsoleLoggingArgs
consoleLoggingParser :: Parser ConsoleLoggingArgs
consoleLoggingParser = do
  WithDisabled ()
commandLogging <- Parser (WithDisabled ())
commandLoggingParser
  WithDisabled (Truncation 'TruncCommandName)
commandNameTrunc <- Parser (WithDisabled (Truncation 'TruncCommandName))
commandNameTruncParser
  WithDisabled LineTruncation
lineTrunc <- Parser (WithDisabled LineTruncation)
lineTruncParser
  WithDisabled (StripControl 'StripControlConsoleLog)
stripControl <- Parser (WithDisabled (StripControl 'StripControlConsoleLog))
stripControlParser
  WithDisabled TimerFormat
timerFormat <- Parser (WithDisabled TimerFormat)
timerFormatParser

  pure
    $ MkConsoleLoggingP
      { WithDisabled ()
SwitchF 'ConfigPhaseArgs ConsoleLogCmdSwitch
commandLogging :: SwitchF 'ConfigPhaseArgs ConsoleLogCmdSwitch
commandLogging :: WithDisabled ()
commandLogging,
        WithDisabled (Truncation 'TruncCommandName)
ConfigPhaseMaybeF 'ConfigPhaseArgs (Truncation 'TruncCommandName)
commandNameTrunc :: ConfigPhaseMaybeF 'ConfigPhaseArgs (Truncation 'TruncCommandName)
commandNameTrunc :: WithDisabled (Truncation 'TruncCommandName)
commandNameTrunc,
        WithDisabled LineTruncation
LineTruncF 'ConfigPhaseArgs
lineTrunc :: LineTruncF 'ConfigPhaseArgs
lineTrunc :: WithDisabled LineTruncation
lineTrunc,
        WithDisabled (StripControl 'StripControlConsoleLog)
ConfigPhaseF
  'ConfigPhaseArgs (StripControl 'StripControlConsoleLog)
stripControl :: ConfigPhaseF
  'ConfigPhaseArgs (StripControl 'StripControlConsoleLog)
stripControl :: WithDisabled (StripControl 'StripControlConsoleLog)
stripControl,
        WithDisabled TimerFormat
ConfigPhaseF 'ConfigPhaseArgs TimerFormat
timerFormat :: ConfigPhaseF 'ConfigPhaseArgs TimerFormat
timerFormat :: WithDisabled TimerFormat
timerFormat
      }

commandLoggingParser :: Parser (WithDisabled ())
commandLoggingParser :: Parser (WithDisabled ())
commandLoggingParser = Parser (Maybe ()) -> String -> Parser (WithDisabled ())
forall a. Parser (Maybe a) -> String -> Parser (WithDisabled a)
Utils.withDisabledParser Parser (Maybe ())
mainParser String
"console-log-command"
  where
    switchParser :: Parser Bool
switchParser =
      Mod FlagFields Bool -> Parser Bool
OA.switch
        ( [Mod FlagFields Bool] -> Mod FlagFields Bool
forall a. Monoid a => [a] -> a
mconcat
            [ String -> Mod FlagFields Bool
forall (f :: Type -> Type) a. HasName f => String -> Mod f a
OA.long String
"console-log-command",
              String -> Mod FlagFields Bool
forall (f :: Type -> Type) a. String -> Mod f a
Utils.mkHelp String
helpTxt
            ]
        )
    mainParser :: Parser (Maybe ())
mainParser = do
      Bool
b <- Parser Bool
switchParser
      pure
        $ if Bool
b
          then () -> Maybe ()
forall a. a -> Maybe a
Just ()
          else Maybe ()
forall a. Maybe a
Nothing
    helpTxt :: String
helpTxt =
      [String] -> String
forall a. Monoid a => [a] -> a
mconcat
        [ String
"The default behavior is to swallow logs for the commands ",
          String
"themselves. This flag gives each command a console region in ",
          String
"which its logs will be printed. Only the latest log per region ",
          String
"is show at a given time."
        ]

commandNameTruncParser :: Parser (WithDisabled (Truncation TruncCommandName))
commandNameTruncParser :: Parser (WithDisabled (Truncation 'TruncCommandName))
commandNameTruncParser = Parser (Maybe (Truncation 'TruncCommandName))
-> String -> Parser (WithDisabled (Truncation 'TruncCommandName))
forall a. Parser (Maybe a) -> String -> Parser (WithDisabled a)
Utils.withDisabledParser Parser (Maybe (Truncation 'TruncCommandName))
mainParser String
"console-log-command-name-trunc"
  where
    mainParser :: Parser (Maybe (Truncation 'TruncCommandName))
mainParser =
      Parser (Truncation 'TruncCommandName)
-> Parser (Maybe (Truncation 'TruncCommandName))
forall (f :: Type -> Type) a. Alternative f => f a -> f (Maybe a)
OA.optional
        (Parser (Truncation 'TruncCommandName)
 -> Parser (Maybe (Truncation 'TruncCommandName)))
-> Parser (Truncation 'TruncCommandName)
-> Parser (Maybe (Truncation 'TruncCommandName))
forall a b. (a -> b) -> a -> b
$ ReadM (Truncation 'TruncCommandName)
-> Mod OptionFields (Truncation 'TruncCommandName)
-> Parser (Truncation 'TruncCommandName)
forall a. ReadM a -> Mod OptionFields a -> Parser a
OA.option
          (ReadM Natural -> ReadM (Truncation 'TruncCommandName)
forall (m :: Type -> Type) (r :: TruncRegion).
MonadFail m =>
m Natural -> m (Truncation r)
Trunc.parseTruncation ReadM Natural
forall a. Read a => ReadM a
Utils.autoStripUnderscores)
          ( [Mod OptionFields (Truncation 'TruncCommandName)]
-> Mod OptionFields (Truncation 'TruncCommandName)
forall a. Monoid a => [a] -> a
mconcat
              [ String -> Mod OptionFields (Truncation 'TruncCommandName)
forall (f :: Type -> Type) a. HasName f => String -> Mod f a
OA.long String
"console-log-command-name-trunc",
                String -> Mod OptionFields (Truncation 'TruncCommandName)
forall (f :: Type -> Type) a. String -> Mod f a
Utils.mkHelp String
helpTxt,
                String -> Mod OptionFields (Truncation 'TruncCommandName)
forall (f :: Type -> Type) a. HasMetavar f => String -> Mod f a
OA.metavar String
"NATURAL"
              ]
          )
    helpTxt :: String
helpTxt =
      [String] -> String
forall a. Monoid a => [a] -> a
mconcat
        [ String
"Non-negative integer that limits the length of commands/key-names ",
          String
"in the console logs. Defaults to no truncation."
        ]

lineTruncParser :: Parser (WithDisabled LineTruncation)
lineTruncParser :: Parser (WithDisabled LineTruncation)
lineTruncParser = Parser (Maybe LineTruncation)
-> String -> Parser (WithDisabled LineTruncation)
forall a. Parser (Maybe a) -> String -> Parser (WithDisabled a)
Utils.withDisabledParser Parser (Maybe LineTruncation)
mainParser String
"console-log-line-trunc"
  where
    mainParser :: Parser (Maybe LineTruncation)
mainParser =
      Parser LineTruncation -> Parser (Maybe LineTruncation)
forall (f :: Type -> Type) a. Alternative f => f a -> f (Maybe a)
OA.optional
        (Parser LineTruncation -> Parser (Maybe LineTruncation))
-> Parser LineTruncation -> Parser (Maybe LineTruncation)
forall a b. (a -> b) -> a -> b
$ ReadM LineTruncation
-> Mod OptionFields LineTruncation -> Parser LineTruncation
forall a. ReadM a -> Mod OptionFields a -> Parser a
OA.option
          (ReadM Natural -> ReadM Text -> ReadM LineTruncation
forall (m :: Type -> Type).
(Alternative m, MonadFail m) =>
m Natural -> m Text -> m LineTruncation
Trunc.parseLineTruncation ReadM Natural
forall a. Read a => ReadM a
Utils.autoStripUnderscores ReadM Text
forall s. IsString s => ReadM s
OA.str)
          ( [Mod OptionFields LineTruncation]
-> Mod OptionFields LineTruncation
forall a. Monoid a => [a] -> a
mconcat
              [ String -> Mod OptionFields LineTruncation
forall (f :: Type -> Type) a. HasName f => String -> Mod f a
OA.long String
"console-log-line-trunc",
                String -> Mod OptionFields LineTruncation
forall (f :: Type -> Type) a. String -> Mod f a
Utils.mkHelp String
helpTxt,
                String -> Mod OptionFields LineTruncation
forall (f :: Type -> Type) a. HasMetavar f => String -> Mod f a
OA.metavar String
"(NATURAL | detect)"
              ]
          )
    helpTxt :: String
helpTxt =
      [String] -> String
forall a. Monoid a => [a] -> a
mconcat
        [ String
"Non-negative integer that limits the length of console logs. Can ",
          String
"also be the string literal 'detect', to detect the terminal size ",
          String
"automatically. Defaults to no truncation. Note that \"log prefixes\" ",
          String
"(e.g. labels like [Success], timestamps) are counted towards the ",
          String
"total length but are never truncated."
        ]

stripControlParser :: Parser (WithDisabled ConsoleLogStripControl)
stripControlParser :: Parser (WithDisabled (StripControl 'StripControlConsoleLog))
stripControlParser =
  Parser (Maybe (StripControl 'StripControlConsoleLog))
-> String
-> Parser (WithDisabled (StripControl 'StripControlConsoleLog))
forall a. Parser (Maybe a) -> String -> Parser (WithDisabled a)
Utils.withDisabledParser Parser (Maybe (StripControl 'StripControlConsoleLog))
mainParser String
"console-log-strip-control"
  where
    mainParser :: Parser (Maybe (StripControl 'StripControlConsoleLog))
mainParser =
      Parser (StripControl 'StripControlConsoleLog)
-> Parser (Maybe (StripControl 'StripControlConsoleLog))
forall (f :: Type -> Type) a. Alternative f => f a -> f (Maybe a)
OA.optional
        (Parser (StripControl 'StripControlConsoleLog)
 -> Parser (Maybe (StripControl 'StripControlConsoleLog)))
-> Parser (StripControl 'StripControlConsoleLog)
-> Parser (Maybe (StripControl 'StripControlConsoleLog))
forall a b. (a -> b) -> a -> b
$ ReadM (StripControl 'StripControlConsoleLog)
-> Mod OptionFields (StripControl 'StripControlConsoleLog)
-> Parser (StripControl 'StripControlConsoleLog)
forall a. ReadM a -> Mod OptionFields a -> Parser a
OA.option
          (ReadM Text -> ReadM (StripControl 'StripControlConsoleLog)
forall (m :: Type -> Type) (t :: StripControlType).
MonadFail m =>
m Text -> m (StripControl t)
StripControl.parseStripControl ReadM Text
forall s. IsString s => ReadM s
OA.str)
          ( [Mod OptionFields (StripControl 'StripControlConsoleLog)]
-> Mod OptionFields (StripControl 'StripControlConsoleLog)
forall a. Monoid a => [a] -> a
mconcat
              [ String -> Mod OptionFields (StripControl 'StripControlConsoleLog)
forall (f :: Type -> Type) a. HasName f => String -> Mod f a
OA.long String
"console-log-strip-control",
                String -> Mod OptionFields (StripControl 'StripControlConsoleLog)
forall (f :: Type -> Type) a. String -> Mod f a
Utils.mkHelp String
helpTxt,
                String -> Mod OptionFields (StripControl 'StripControlConsoleLog)
forall (f :: Type -> Type) a. HasMetavar f => String -> Mod f a
OA.metavar String
"(all | smart | none)"
              ]
          )
    helpTxt :: String
helpTxt =
      [String] -> String
forall a. Monoid a => [a] -> a
mconcat
        [ String
"Control characters can wreak layout havoc, thus we include this",
          String
" option. 'all' strips all",
          String
" such chars. 'none' does nothing i.e. all chars are left",
          String
" untouched. The default 'smart' attempts to strip",
          String
" only the control chars that affect layout (e.g. cursor movements) and",
          String
" leaves others unaffected (e.g. colors). This has the potential",
          String
" to be the 'prettiest' though it is possible to miss some chars.",
          String
" This option is experimental and subject to change."
        ]

timerFormatParser :: Parser (WithDisabled TimerFormat)
timerFormatParser :: Parser (WithDisabled TimerFormat)
timerFormatParser = Parser (Maybe TimerFormat)
-> String -> Parser (WithDisabled TimerFormat)
forall a. Parser (Maybe a) -> String -> Parser (WithDisabled a)
Utils.withDisabledParser Parser (Maybe TimerFormat)
mainParser String
"console-log-timer-format"
  where
    mainParser :: Parser (Maybe TimerFormat)
mainParser =
      Parser TimerFormat -> Parser (Maybe TimerFormat)
forall (f :: Type -> Type) a. Alternative f => f a -> f (Maybe a)
OA.optional
        (Parser TimerFormat -> Parser (Maybe TimerFormat))
-> Parser TimerFormat -> Parser (Maybe TimerFormat)
forall a b. (a -> b) -> a -> b
$ ReadM TimerFormat
-> Mod OptionFields TimerFormat -> Parser TimerFormat
forall a. ReadM a -> Mod OptionFields a -> Parser a
OA.option (ReadM Text -> ReadM TimerFormat
forall (m :: Type -> Type). MonadFail m => m Text -> m TimerFormat
TimerFormat.parseTimerFormat ReadM Text
forall s. IsString s => ReadM s
OA.str)
        (Mod OptionFields TimerFormat -> Parser TimerFormat)
-> Mod OptionFields TimerFormat -> Parser TimerFormat
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields TimerFormat] -> Mod OptionFields TimerFormat
forall a. Monoid a => [a] -> a
mconcat
          [ String -> Mod OptionFields TimerFormat
forall (f :: Type -> Type) a. HasName f => String -> Mod f a
OA.long String
"console-log-timer-format",
            String -> Mod OptionFields TimerFormat
forall (f :: Type -> Type) a. String -> Mod f a
Utils.mkHelp String
helpTxt,
            String -> Mod OptionFields TimerFormat
forall (f :: Type -> Type) a. HasMetavar f => String -> Mod f a
OA.metavar String
forall a. IsString a => a
TimerFormat.timerFormatStr
          ]
    helpTxt :: String
helpTxt =
      [String] -> String
forall a. Monoid a => [a] -> a
mconcat
        [ String
"How to format the timer. Defaults to prose_compact e.g. ",
          String
"'2 hours, 3 seconds'."
        ]