-- | CLI parsing for CommandLoggingArgs
module Shrun.Configuration.Args.Parsing.CommandLogging
  ( commandLoggingParser,
  )
where

import Data.Text qualified as T
import Options.Applicative (Parser)
import Options.Applicative qualified as OA
import Shrun.Configuration.Args.Parsing.Utils qualified as Utils
import Shrun.Configuration.Data.CommandLogging
  ( CommandLoggingArgs,
    CommandLoggingP
      ( MkCommandLoggingP,
        pollInterval,
        readSize,
        reportReadErrors
      ),
  )
import Shrun.Configuration.Data.CommandLogging.PollInterval (PollInterval)
import Shrun.Configuration.Data.CommandLogging.PollInterval qualified as PollInterval
import Shrun.Configuration.Data.CommandLogging.ReadSize (ReadSize)
import Shrun.Configuration.Data.CommandLogging.ReadSize qualified as ReadSize
import Shrun.Configuration.Data.WithDisabled (WithDisabled)
import Shrun.Configuration.Default (Default (def))
import Shrun.Prelude

commandLoggingParser :: Parser CommandLoggingArgs
commandLoggingParser :: Parser CommandLoggingArgs
commandLoggingParser = do
  WithDisabled PollInterval
pollInterval <- Parser (WithDisabled PollInterval)
pollIntervalParser
  WithDisabled ReadSize
readSize <- Parser (WithDisabled ReadSize)
readSizeParser
  WithDisabled ()
reportReadErrors <- Parser (WithDisabled ())
reportReadErrorsParser

  pure
    $ MkCommandLoggingP
      { WithDisabled PollInterval
ConfigPhaseF 'ConfigPhaseArgs PollInterval
pollInterval :: ConfigPhaseF 'ConfigPhaseArgs PollInterval
pollInterval :: WithDisabled PollInterval
pollInterval,
        WithDisabled ReadSize
ConfigPhaseF 'ConfigPhaseArgs ReadSize
readSize :: ConfigPhaseF 'ConfigPhaseArgs ReadSize
readSize :: WithDisabled ReadSize
readSize,
        WithDisabled ()
SwitchF 'ConfigPhaseArgs ReportReadErrorsSwitch
reportReadErrors :: SwitchF 'ConfigPhaseArgs ReportReadErrorsSwitch
reportReadErrors :: WithDisabled ()
reportReadErrors
      }

pollIntervalParser :: Parser (WithDisabled PollInterval)
pollIntervalParser :: Parser (WithDisabled PollInterval)
pollIntervalParser = Parser (Maybe PollInterval)
-> String -> Parser (WithDisabled PollInterval)
forall a. Parser (Maybe a) -> String -> Parser (WithDisabled a)
Utils.withDisabledParser Parser (Maybe PollInterval)
mainParser String
"command-log-poll-interval"
  where
    mainParser :: Parser (Maybe PollInterval)
mainParser =
      Parser PollInterval -> Parser (Maybe PollInterval)
forall (f :: Type -> Type) a. Alternative f => f a -> f (Maybe a)
OA.optional
        (Parser PollInterval -> Parser (Maybe PollInterval))
-> Parser PollInterval -> Parser (Maybe PollInterval)
forall a b. (a -> b) -> a -> b
$ ReadM PollInterval
-> Mod OptionFields PollInterval -> Parser PollInterval
forall a. ReadM a -> Mod OptionFields a -> Parser a
OA.option
          (ReadM Natural -> ReadM PollInterval
forall (m :: Type -> Type).
Functor m =>
m Natural -> m PollInterval
PollInterval.parsePollInterval ReadM Natural
forall a. Read a => ReadM a
Utils.autoStripUnderscores)
          ( [Mod OptionFields PollInterval] -> Mod OptionFields PollInterval
forall a. Monoid a => [a] -> a
mconcat
              [ String -> Mod OptionFields PollInterval
forall (f :: Type -> Type) a. HasName f => String -> Mod f a
OA.long String
"command-log-poll-interval",
                String -> Mod OptionFields PollInterval
forall (f :: Type -> Type) a. String -> Mod f a
Utils.mkHelp String
helpTxt,
                String -> Mod OptionFields PollInterval
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 used in conjunction with --console-log-command and ",
          String
"--file-log that determines how quickly we poll commands for ",
          String
"logs, in microseconds. A value of 0 is interpreted as infinite ",
          String
"i.e. limited only by the CPU. Defaults to ",
          PollInterval -> String
prettyPollInterval PollInterval
forall a. Default a => a
def,
          String
". Note that lower values will increase CPU usage. In particular, ",
          String
"0 will max out a CPU thread."
        ]

    prettyPollInterval :: PollInterval -> String
    prettyPollInterval :: PollInterval -> String
prettyPollInterval =
      Text -> String
unpack
        (Text -> String)
-> (PollInterval -> Text) -> PollInterval -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.reverse
        (Text -> Text) -> (PollInterval -> Text) -> PollInterval -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Text] -> Text
T.intercalate Text
","
        ([Text] -> Text)
-> (PollInterval -> [Text]) -> PollInterval -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Text -> [Text]
T.chunksOf Int
3
        (Text -> [Text])
-> (PollInterval -> Text) -> PollInterval -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.reverse
        (Text -> Text) -> (PollInterval -> Text) -> PollInterval -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Natural -> Text
forall a. Show a => a -> Text
showt
        (Natural -> Text)
-> (PollInterval -> Natural) -> PollInterval -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Optic' An_Iso NoIx PollInterval Natural -> PollInterval -> Natural
forall k (is :: IxList) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view Optic' An_Iso NoIx PollInterval Natural
#unPollInterval

readSizeParser :: Parser (WithDisabled ReadSize)
readSizeParser :: Parser (WithDisabled ReadSize)
readSizeParser = Parser (Maybe ReadSize) -> String -> Parser (WithDisabled ReadSize)
forall a. Parser (Maybe a) -> String -> Parser (WithDisabled a)
Utils.withDisabledParser Parser (Maybe ReadSize)
mainParser String
"command-log-read-size"
  where
    mainParser :: Parser (Maybe ReadSize)
mainParser =
      Parser ReadSize -> Parser (Maybe ReadSize)
forall (f :: Type -> Type) a. Alternative f => f a -> f (Maybe a)
OA.optional
        (Parser ReadSize -> Parser (Maybe ReadSize))
-> Parser ReadSize -> Parser (Maybe ReadSize)
forall a b. (a -> b) -> a -> b
$ ReadM ReadSize -> Mod OptionFields ReadSize -> Parser ReadSize
forall a. ReadM a -> Mod OptionFields a -> Parser a
OA.option
          (ReadM Text -> ReadM ReadSize
forall (m :: Type -> Type). MonadFail m => m Text -> m ReadSize
ReadSize.parseReadSize ReadM Text
forall s. IsString s => ReadM s
OA.str)
          ( [Mod OptionFields ReadSize] -> Mod OptionFields ReadSize
forall a. Monoid a => [a] -> a
mconcat
              [ String -> Mod OptionFields ReadSize
forall (f :: Type -> Type) a. HasName f => String -> Mod f a
OA.long String
"command-log-read-size",
                String -> Mod OptionFields ReadSize
forall (f :: Type -> Type) a. String -> Mod f a
Utils.mkHelp String
helpTxt,
                String -> Mod OptionFields ReadSize
forall (f :: Type -> Type) a. HasMetavar f => String -> Mod f a
OA.metavar String
"BYTES"
              ]
          )

    helpTxt :: String
helpTxt =
      [String] -> String
forall a. Monoid a => [a] -> a
mconcat
        [ String
"The max number of bytes in a single read when streaming command ",
          String
"logs (--console-log-command and --file-log). Logs larger than ",
          String
"--command-log-read-size will be read in a subsequent read, hence ",
          String
"broken across lines. The default is '16 kb'."
        ]

reportReadErrorsParser :: Parser (WithDisabled ())
reportReadErrorsParser :: Parser (WithDisabled ())
reportReadErrorsParser =
  Mod FlagFields Bool
-> Parser (Maybe ()) -> String -> Parser (WithDisabled ())
forall a.
Mod FlagFields Bool
-> Parser (Maybe a) -> String -> Parser (WithDisabled a)
Utils.withDisabledParserOpts
    Mod FlagFields Bool
forall (f :: Type -> Type) a. Mod f a
OA.internal
    Parser (Maybe ())
mainParser
    String
"command-log-report-read-errors"
  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
"command-log-report-read-errors",
              Mod FlagFields Bool
forall (f :: Type -> Type) a. Mod f a
OA.internal,
              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
"If active, logs read errors when streaming commands."