{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE FlexibleInstances #-}

module Cardano.CLI.Option.Flag.Type
  ( Flag (..)
  , Defaultness (..)
  , FlagOptions (..)
  , defaultFlagOptions
  )
where

import GHC.Generics

data Defaultness
  = IsDefault
  | NonDefault
  deriving (Int -> Defaultness -> ShowS
[Defaultness] -> ShowS
Defaultness -> String
(Int -> Defaultness -> ShowS)
-> (Defaultness -> String)
-> ([Defaultness] -> ShowS)
-> Show Defaultness
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Defaultness -> ShowS
showsPrec :: Int -> Defaultness -> ShowS
$cshow :: Defaultness -> String
show :: Defaultness -> String
$cshowList :: [Defaultness] -> ShowS
showList :: [Defaultness] -> ShowS
Show, Defaultness -> Defaultness -> Bool
(Defaultness -> Defaultness -> Bool)
-> (Defaultness -> Defaultness -> Bool) -> Eq Defaultness
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Defaultness -> Defaultness -> Bool
== :: Defaultness -> Defaultness -> Bool
$c/= :: Defaultness -> Defaultness -> Bool
/= :: Defaultness -> Defaultness -> Bool
Eq, (forall x. Defaultness -> Rep Defaultness x)
-> (forall x. Rep Defaultness x -> Defaultness)
-> Generic Defaultness
forall x. Rep Defaultness x -> Defaultness
forall x. Defaultness -> Rep Defaultness x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Defaultness -> Rep Defaultness x
from :: forall x. Defaultness -> Rep Defaultness x
$cto :: forall x. Rep Defaultness x -> Defaultness
to :: forall x. Rep Defaultness x -> Defaultness
Generic)

-- | Options for a flag that control how it is rendered and parsed.
newtype FlagOptions = FlagOptions
  { FlagOptions -> Defaultness
isDefault :: Defaultness
  -- ^ Whether the flag is a default value.
  }
  deriving (Int -> FlagOptions -> ShowS
[FlagOptions] -> ShowS
FlagOptions -> String
(Int -> FlagOptions -> ShowS)
-> (FlagOptions -> String)
-> ([FlagOptions] -> ShowS)
-> Show FlagOptions
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> FlagOptions -> ShowS
showsPrec :: Int -> FlagOptions -> ShowS
$cshow :: FlagOptions -> String
show :: FlagOptions -> String
$cshowList :: [FlagOptions] -> ShowS
showList :: [FlagOptions] -> ShowS
Show, FlagOptions -> FlagOptions -> Bool
(FlagOptions -> FlagOptions -> Bool)
-> (FlagOptions -> FlagOptions -> Bool) -> Eq FlagOptions
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: FlagOptions -> FlagOptions -> Bool
== :: FlagOptions -> FlagOptions -> Bool
$c/= :: FlagOptions -> FlagOptions -> Bool
/= :: FlagOptions -> FlagOptions -> Bool
Eq, (forall x. FlagOptions -> Rep FlagOptions x)
-> (forall x. Rep FlagOptions x -> FlagOptions)
-> Generic FlagOptions
forall x. Rep FlagOptions x -> FlagOptions
forall x. FlagOptions -> Rep FlagOptions x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. FlagOptions -> Rep FlagOptions x
from :: forall x. FlagOptions -> Rep FlagOptions x
$cto :: forall x. Rep FlagOptions x -> FlagOptions
to :: forall x. Rep FlagOptions x -> FlagOptions
Generic)

-- instance Semigroup FlagOptions where
--   FlagOptions IsDefault <> FlagOptions _ = FlagOptions IsDefault
--   FlagOptions _ <> FlagOptions IsDefault = FlagOptions IsDefault
--   FlagOptions _ <> FlagOptions _ = FlagOptions NonDefault

-- instance Monoid FlagOptions where
--   mempty = FlagOptions NonDefault
--   mappend = (<>)

-- | A flag that can be used in the command line interface.
--
-- It contains information about how to render the flag, its long name,
-- its content, and its value.
-- The type variable 'a' represents the type of the value that the flag holds.
--
-- The reason for this type instead of using 'Parser a' directly is to
-- allow for more complex parsing logic, such as handling default values.
data Flag a = Flag
  { forall a. Flag a -> String
longName :: String
  , forall a. Flag a -> String
format :: String
  , forall a. Flag a -> FlagOptions
options :: FlagOptions
  , forall a. Flag a -> a
value :: a
  }
  deriving (Int -> Flag a -> ShowS
[Flag a] -> ShowS
Flag a -> String
(Int -> Flag a -> ShowS)
-> (Flag a -> String) -> ([Flag a] -> ShowS) -> Show (Flag a)
forall a. Show a => Int -> Flag a -> ShowS
forall a. Show a => [Flag a] -> ShowS
forall a. Show a => Flag a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Flag a -> ShowS
showsPrec :: Int -> Flag a -> ShowS
$cshow :: forall a. Show a => Flag a -> String
show :: Flag a -> String
$cshowList :: forall a. Show a => [Flag a] -> ShowS
showList :: [Flag a] -> ShowS
Show, Flag a -> Flag a -> Bool
(Flag a -> Flag a -> Bool)
-> (Flag a -> Flag a -> Bool) -> Eq (Flag a)
forall a. Eq a => Flag a -> Flag a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Flag a -> Flag a -> Bool
== :: Flag a -> Flag a -> Bool
$c/= :: forall a. Eq a => Flag a -> Flag a -> Bool
/= :: Flag a -> Flag a -> Bool
Eq, (forall x. Flag a -> Rep (Flag a) x)
-> (forall x. Rep (Flag a) x -> Flag a) -> Generic (Flag a)
forall x. Rep (Flag a) x -> Flag a
forall x. Flag a -> Rep (Flag a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Flag a) x -> Flag a
forall a x. Flag a -> Rep (Flag a) x
$cfrom :: forall a x. Flag a -> Rep (Flag a) x
from :: forall x. Flag a -> Rep (Flag a) x
$cto :: forall a x. Rep (Flag a) x -> Flag a
to :: forall x. Rep (Flag a) x -> Flag a
Generic)

defaultFlagOptions :: FlagOptions
defaultFlagOptions :: FlagOptions
defaultFlagOptions = Defaultness -> FlagOptions
FlagOptions Defaultness
NonDefault