{-# LANGUAGE UndecidableInstances #-}

module Shrun.Configuration.Data.CommonLogging
  ( -- * Types
    CommonLoggingP (..),
    CommonLoggingArgs,
    CommonLoggingToml,
    CommonLoggingMerged,
    CommonLoggingEnv,

    -- * Functions
    mergeCommonLogging,
    toEnv,

    -- * Misc
    defaultMerged,
  )
where

import Shrun.Configuration.Data.CommonLogging.KeyHideSwitch (KeyHideSwitch)
import Shrun.Configuration.Data.ConfigPhase
  ( ConfigPhase
      ( ConfigPhaseArgs,
        ConfigPhaseEnv,
        ConfigPhaseMerged,
        ConfigPhaseToml
      ),
    ConfigPhaseF,
  )
import Shrun.Configuration.Data.WithDisabled ((<>?.))
import Shrun.Configuration.Default (Default (def))
import Shrun.Prelude

-- | Holds command logging config.
type CommonLoggingP :: ConfigPhase -> Type
newtype CommonLoggingP p = MkCommonLoggingP
  { -- | Whether to display command by (key) name or command.
    forall (p :: ConfigPhase).
CommonLoggingP p -> ConfigPhaseF p KeyHideSwitch
keyHide :: ConfigPhaseF p KeyHideSwitch
  }

instance
  (k ~ An_Iso, a ~ ConfigPhaseF p KeyHideSwitch, b ~ ConfigPhaseF p KeyHideSwitch) =>
  LabelOptic "keyHide" k (CommonLoggingP p) (CommonLoggingP p) a b
  where
  labelOptic :: Optic k NoIx (CommonLoggingP p) (CommonLoggingP p) a b
labelOptic = (CommonLoggingP p -> a)
-> (b -> CommonLoggingP p)
-> Iso (CommonLoggingP p) (CommonLoggingP p) a b
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso (\(MkCommonLoggingP ConfigPhaseF p KeyHideSwitch
kh) -> a
ConfigPhaseF p KeyHideSwitch
kh) b -> CommonLoggingP p
ConfigPhaseF p KeyHideSwitch -> CommonLoggingP p
forall (p :: ConfigPhase).
ConfigPhaseF p KeyHideSwitch -> CommonLoggingP p
MkCommonLoggingP
  {-# INLINE labelOptic #-}

type CommonLoggingArgs = CommonLoggingP ConfigPhaseArgs

type CommonLoggingToml = CommonLoggingP ConfigPhaseToml

type CommonLoggingMerged = CommonLoggingP ConfigPhaseMerged

type CommonLoggingEnv = CommonLoggingP ConfigPhaseEnv

deriving stock instance Eq (CommonLoggingP ConfigPhaseArgs)

deriving stock instance Show (CommonLoggingP ConfigPhaseArgs)

deriving stock instance Eq (CommonLoggingP ConfigPhaseToml)

deriving stock instance Show (CommonLoggingP ConfigPhaseToml)

deriving stock instance Eq (CommonLoggingP ConfigPhaseMerged)

deriving stock instance Show (CommonLoggingP ConfigPhaseMerged)

instance
  (Default (ConfigPhaseF p KeyHideSwitch)) =>
  Default (CommonLoggingP p)
  where
  def :: CommonLoggingP p
def = ConfigPhaseF p KeyHideSwitch -> CommonLoggingP p
forall (p :: ConfigPhase).
ConfigPhaseF p KeyHideSwitch -> CommonLoggingP p
MkCommonLoggingP ConfigPhaseF p KeyHideSwitch
forall a. Default a => a
def

-- | Merges args and toml configs.
mergeCommonLogging ::
  CommonLoggingArgs ->
  Maybe CommonLoggingToml ->
  CommonLoggingMerged
mergeCommonLogging :: CommonLoggingArgs -> Maybe CommonLoggingToml -> CommonLoggingMerged
mergeCommonLogging CommonLoggingArgs
args Maybe CommonLoggingToml
mToml =
  MkCommonLoggingP
    { keyHide :: ConfigPhaseF 'ConfigPhaseMerged KeyHideSwitch
keyHide =
        (CommonLoggingArgs
args CommonLoggingArgs
-> Optic'
     An_Iso NoIx CommonLoggingArgs (WithDisabled KeyHideSwitch)
-> WithDisabled KeyHideSwitch
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' An_Iso NoIx CommonLoggingArgs (WithDisabled KeyHideSwitch)
#keyHide) WithDisabled KeyHideSwitch -> Maybe KeyHideSwitch -> KeyHideSwitch
forall a. Default a => WithDisabled a -> Maybe a -> a
<>?. (CommonLoggingToml
toml CommonLoggingToml
-> Optic' An_Iso NoIx CommonLoggingToml (Maybe KeyHideSwitch)
-> Maybe KeyHideSwitch
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' An_Iso NoIx CommonLoggingToml (Maybe KeyHideSwitch)
#keyHide)
    }
  where
    toml :: CommonLoggingToml
toml = CommonLoggingToml -> Maybe CommonLoggingToml -> CommonLoggingToml
forall a. a -> Maybe a -> a
fromMaybe CommonLoggingToml
defaultToml Maybe CommonLoggingToml
mToml

instance DecodeTOML CommonLoggingToml where
  tomlDecoder :: Decoder CommonLoggingToml
tomlDecoder =
    Maybe KeyHideSwitch -> CommonLoggingToml
ConfigPhaseF 'ConfigPhaseToml KeyHideSwitch -> CommonLoggingToml
forall (p :: ConfigPhase).
ConfigPhaseF p KeyHideSwitch -> CommonLoggingP p
MkCommonLoggingP
      (Maybe KeyHideSwitch -> CommonLoggingToml)
-> Decoder (Maybe KeyHideSwitch) -> Decoder CommonLoggingToml
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder (Maybe KeyHideSwitch)
decodeKeyHideSwitch

decodeKeyHideSwitch :: Decoder (Maybe KeyHideSwitch)
decodeKeyHideSwitch :: Decoder (Maybe KeyHideSwitch)
decodeKeyHideSwitch = Decoder KeyHideSwitch -> Text -> Decoder (Maybe KeyHideSwitch)
forall a. Decoder a -> Text -> Decoder (Maybe a)
getFieldOptWith Decoder KeyHideSwitch
forall a. DecodeTOML a => Decoder a
tomlDecoder Text
"key-hide"

-- | Creates env version from merged.
toEnv :: CommonLoggingMerged -> CommonLoggingEnv
toEnv :: CommonLoggingMerged -> CommonLoggingEnv
toEnv CommonLoggingMerged
merged =
  MkCommonLoggingP
    { keyHide :: ConfigPhaseF 'ConfigPhaseEnv KeyHideSwitch
keyHide = CommonLoggingMerged
merged CommonLoggingMerged
-> Optic' An_Iso NoIx CommonLoggingMerged KeyHideSwitch
-> KeyHideSwitch
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' An_Iso NoIx CommonLoggingMerged KeyHideSwitch
#keyHide
    }

defaultToml :: CommonLoggingToml
defaultToml :: CommonLoggingToml
defaultToml =
  MkCommonLoggingP
    { keyHide :: ConfigPhaseF 'ConfigPhaseToml KeyHideSwitch
keyHide = Maybe KeyHideSwitch
ConfigPhaseF 'ConfigPhaseToml KeyHideSwitch
forall a. Maybe a
Nothing
    }

defaultMerged :: CommonLoggingMerged
defaultMerged :: CommonLoggingMerged
defaultMerged =
  MkCommonLoggingP
    { keyHide :: ConfigPhaseF 'ConfigPhaseMerged KeyHideSwitch
keyHide = ConfigPhaseF 'ConfigPhaseMerged KeyHideSwitch
KeyHideSwitch
forall a. Default a => a
def
    }