{-# LANGUAGE TemplateHaskell #-}

-- | Command groups
module CalamityCommands.Group (Group (..)) where

import CalamityCommands.AliasType
import CalamityCommands.Check
import {-# SOURCE #-} CalamityCommands.Command
import qualified Data.HashMap.Lazy as LH
import Data.List.NonEmpty (NonEmpty)
import qualified Data.List.NonEmpty as NE
import qualified Data.Text as T
import Optics
import qualified TextShow
import TextShow.TH (deriveTextShow)

-- | A group of commands
data Group m c a = Group
  { Group m c a -> NonEmpty Text
names :: NonEmpty T.Text
  , Group m c a -> Maybe (Group m c a)
parent :: Maybe (Group m c a)
  , Group m c a -> Bool
hidden :: Bool
  , -- | Any child commands of this group
    Group m c a -> HashMap Text (Command m c a, AliasType)
commands :: LH.HashMap T.Text (Command m c a, AliasType)
  , -- | Any child groups of this group
    Group m c a -> HashMap Text (Group m c a, AliasType)
children :: LH.HashMap T.Text (Group m c a, AliasType)
  , -- | A function producing the \'help\' for the group
    Group m c a -> c -> Text
help :: c -> T.Text
  , -- | A list of checks that must pass
    Group m c a -> [Check m c]
checks :: [Check m c]
  }

$(makeFieldLabelsNoPrefix ''Group)

data GroupS m c a = GroupS
  { GroupS m c a -> NonEmpty Text
names :: NonEmpty T.Text
  , GroupS m c a -> Maybe Text
parent :: Maybe T.Text
  , GroupS m c a -> [(Text, (Command m c a, AliasType))]
commands :: [(T.Text, (Command m c a, AliasType))]
  , GroupS m c a -> [(Text, (Group m c a, AliasType))]
children :: [(T.Text, (Group m c a, AliasType))]
  , GroupS m c a -> Bool
hidden :: Bool
  }
  deriving (Int -> GroupS m c a -> ShowS
[GroupS m c a] -> ShowS
GroupS m c a -> String
(Int -> GroupS m c a -> ShowS)
-> (GroupS m c a -> String)
-> ([GroupS m c a] -> ShowS)
-> Show (GroupS m c a)
forall (a :: OpticKind).
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (m :: OpticKind -> OpticKind) (c :: OpticKind)
       (a :: OpticKind).
(Show a, Show c) =>
Int -> GroupS m c a -> ShowS
forall (m :: OpticKind -> OpticKind) (c :: OpticKind)
       (a :: OpticKind).
(Show a, Show c) =>
[GroupS m c a] -> ShowS
forall (m :: OpticKind -> OpticKind) (c :: OpticKind)
       (a :: OpticKind).
(Show a, Show c) =>
GroupS m c a -> String
showList :: [GroupS m c a] -> ShowS
$cshowList :: forall (m :: OpticKind -> OpticKind) (c :: OpticKind)
       (a :: OpticKind).
(Show a, Show c) =>
[GroupS m c a] -> ShowS
show :: GroupS m c a -> String
$cshow :: forall (m :: OpticKind -> OpticKind) (c :: OpticKind)
       (a :: OpticKind).
(Show a, Show c) =>
GroupS m c a -> String
showsPrec :: Int -> GroupS m c a -> ShowS
$cshowsPrec :: forall (m :: OpticKind -> OpticKind) (c :: OpticKind)
       (a :: OpticKind).
(Show a, Show c) =>
Int -> GroupS m c a -> ShowS
Show)

instance (Show a, Show c) => Show (Group m c a) where
  showsPrec :: Int -> Group m c a -> ShowS
showsPrec Int
d Group {NonEmpty Text
names :: NonEmpty Text
$sel:names:Group :: forall (m :: OpticKind -> OpticKind) (c :: OpticKind)
       (a :: OpticKind).
Group m c a -> NonEmpty Text
names, Maybe (Group m c a)
parent :: Maybe (Group m c a)
$sel:parent:Group :: forall (m :: OpticKind -> OpticKind) (c :: OpticKind)
       (a :: OpticKind).
Group m c a -> Maybe (Group m c a)
parent, HashMap Text (Command m c a, AliasType)
commands :: HashMap Text (Command m c a, AliasType)
$sel:commands:Group :: forall (m :: OpticKind -> OpticKind) (c :: OpticKind)
       (a :: OpticKind).
Group m c a -> HashMap Text (Command m c a, AliasType)
commands, HashMap Text (Group m c a, AliasType)
children :: HashMap Text (Group m c a, AliasType)
$sel:children:Group :: forall (m :: OpticKind -> OpticKind) (c :: OpticKind)
       (a :: OpticKind).
Group m c a -> HashMap Text (Group m c a, AliasType)
children, Bool
hidden :: Bool
$sel:hidden:Group :: forall (m :: OpticKind -> OpticKind) (c :: OpticKind)
       (a :: OpticKind).
Group m c a -> Bool
hidden} =
    Int -> GroupS m c a -> ShowS
forall (a :: OpticKind). Show a => Int -> a -> ShowS
showsPrec Int
d (GroupS m c a -> ShowS) -> GroupS m c a -> ShowS
forall (a :: OpticKind) b. (a -> b) -> a -> b
$ NonEmpty Text
-> Maybe Text
-> [(Text, (Command m c a, AliasType))]
-> [(Text, (Group m c a, AliasType))]
-> Bool
-> GroupS m c a
forall (m :: OpticKind -> OpticKind) (c :: OpticKind)
       (a :: OpticKind).
NonEmpty Text
-> Maybe Text
-> [(Text, (Command m c a, AliasType))]
-> [(Text, (Group m c a, AliasType))]
-> Bool
-> GroupS m c a
GroupS NonEmpty Text
names (NonEmpty Text -> Text
forall (a :: OpticKind). NonEmpty a -> a
NE.head (NonEmpty Text -> Text) -> Maybe (NonEmpty Text) -> Maybe Text
forall (f :: OpticKind -> OpticKind) (a :: OpticKind)
       (b :: OpticKind).
Functor f =>
(a -> b) -> f a -> f b
<$> Maybe (Group m c a)
parent Maybe (Group m c a)
-> Optic'
     An_AffineTraversal NoIx (Maybe (Group m c a)) (NonEmpty Text)
-> Maybe (NonEmpty Text)
forall (k :: OpticKind) (s :: OpticKind) (is :: IxList)
       (a :: OpticKind).
Is k An_AffineFold =>
s -> Optic' k is s a -> Maybe a
^? Prism
  (Maybe (Group m c a))
  (Maybe (Group m c a))
  (Group m c a)
  (Group m c a)
forall (a :: OpticKind) (b :: OpticKind).
Prism (Maybe a) (Maybe b) a b
_Just Prism
  (Maybe (Group m c a))
  (Maybe (Group m c a))
  (Group m c a)
  (Group m c a)
-> Optic
     A_Lens
     NoIx
     (Group m c a)
     (Group m c a)
     (NonEmpty Text)
     (NonEmpty Text)
-> Optic'
     An_AffineTraversal NoIx (Maybe (Group m c a)) (NonEmpty Text)
forall (k :: OpticKind) (l :: OpticKind) (m :: OpticKind)
       (is :: IxList) (js :: IxList) (ks :: IxList) (s :: OpticKind)
       (t :: OpticKind) (u :: OpticKind) (v :: OpticKind) (a :: OpticKind)
       (b :: OpticKind).
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% IsLabel
  "names"
  (Optic
     A_Lens
     NoIx
     (Group m c a)
     (Group m c a)
     (NonEmpty Text)
     (NonEmpty Text))
Optic
  A_Lens
  NoIx
  (Group m c a)
  (Group m c a)
  (NonEmpty Text)
  (NonEmpty Text)
#names) (HashMap Text (Command m c a, AliasType)
-> [(Text, (Command m c a, AliasType))]
forall (k :: OpticKind) (v :: OpticKind). HashMap k v -> [(k, v)]
LH.toList HashMap Text (Command m c a, AliasType)
commands) (HashMap Text (Group m c a, AliasType)
-> [(Text, (Group m c a, AliasType))]
forall (k :: OpticKind) (v :: OpticKind). HashMap k v -> [(k, v)]
LH.toList HashMap Text (Group m c a, AliasType)
children) Bool
hidden

$(deriveTextShow ''GroupS)

instance (TextShow.TextShow a, TextShow.TextShow c) => TextShow.TextShow (Group m c a) where
  showbPrec :: Int -> Group m c a -> Builder
showbPrec Int
d Group {NonEmpty Text
names :: NonEmpty Text
$sel:names:Group :: forall (m :: OpticKind -> OpticKind) (c :: OpticKind)
       (a :: OpticKind).
Group m c a -> NonEmpty Text
names, Maybe (Group m c a)
parent :: Maybe (Group m c a)
$sel:parent:Group :: forall (m :: OpticKind -> OpticKind) (c :: OpticKind)
       (a :: OpticKind).
Group m c a -> Maybe (Group m c a)
parent, HashMap Text (Command m c a, AliasType)
commands :: HashMap Text (Command m c a, AliasType)
$sel:commands:Group :: forall (m :: OpticKind -> OpticKind) (c :: OpticKind)
       (a :: OpticKind).
Group m c a -> HashMap Text (Command m c a, AliasType)
commands, HashMap Text (Group m c a, AliasType)
children :: HashMap Text (Group m c a, AliasType)
$sel:children:Group :: forall (m :: OpticKind -> OpticKind) (c :: OpticKind)
       (a :: OpticKind).
Group m c a -> HashMap Text (Group m c a, AliasType)
children, Bool
hidden :: Bool
$sel:hidden:Group :: forall (m :: OpticKind -> OpticKind) (c :: OpticKind)
       (a :: OpticKind).
Group m c a -> Bool
hidden} =
    Int -> GroupS m c a -> Builder
forall (a :: OpticKind). TextShow a => Int -> a -> Builder
TextShow.showbPrec Int
d (GroupS m c a -> Builder) -> GroupS m c a -> Builder
forall (a :: OpticKind) b. (a -> b) -> a -> b
$ NonEmpty Text
-> Maybe Text
-> [(Text, (Command m c a, AliasType))]
-> [(Text, (Group m c a, AliasType))]
-> Bool
-> GroupS m c a
forall (m :: OpticKind -> OpticKind) (c :: OpticKind)
       (a :: OpticKind).
NonEmpty Text
-> Maybe Text
-> [(Text, (Command m c a, AliasType))]
-> [(Text, (Group m c a, AliasType))]
-> Bool
-> GroupS m c a
GroupS NonEmpty Text
names (NonEmpty Text -> Text
forall (a :: OpticKind). NonEmpty a -> a
NE.head (NonEmpty Text -> Text) -> Maybe (NonEmpty Text) -> Maybe Text
forall (f :: OpticKind -> OpticKind) (a :: OpticKind)
       (b :: OpticKind).
Functor f =>
(a -> b) -> f a -> f b
<$> Maybe (Group m c a)
parent Maybe (Group m c a)
-> Optic'
     An_AffineTraversal NoIx (Maybe (Group m c a)) (NonEmpty Text)
-> Maybe (NonEmpty Text)
forall (k :: OpticKind) (s :: OpticKind) (is :: IxList)
       (a :: OpticKind).
Is k An_AffineFold =>
s -> Optic' k is s a -> Maybe a
^? Prism
  (Maybe (Group m c a))
  (Maybe (Group m c a))
  (Group m c a)
  (Group m c a)
forall (a :: OpticKind) (b :: OpticKind).
Prism (Maybe a) (Maybe b) a b
_Just Prism
  (Maybe (Group m c a))
  (Maybe (Group m c a))
  (Group m c a)
  (Group m c a)
-> Optic
     A_Lens
     NoIx
     (Group m c a)
     (Group m c a)
     (NonEmpty Text)
     (NonEmpty Text)
-> Optic'
     An_AffineTraversal NoIx (Maybe (Group m c a)) (NonEmpty Text)
forall (k :: OpticKind) (l :: OpticKind) (m :: OpticKind)
       (is :: IxList) (js :: IxList) (ks :: IxList) (s :: OpticKind)
       (t :: OpticKind) (u :: OpticKind) (v :: OpticKind) (a :: OpticKind)
       (b :: OpticKind).
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% IsLabel
  "names"
  (Optic
     A_Lens
     NoIx
     (Group m c a)
     (Group m c a)
     (NonEmpty Text)
     (NonEmpty Text))
Optic
  A_Lens
  NoIx
  (Group m c a)
  (Group m c a)
  (NonEmpty Text)
  (NonEmpty Text)
#names) (HashMap Text (Command m c a, AliasType)
-> [(Text, (Command m c a, AliasType))]
forall (k :: OpticKind) (v :: OpticKind). HashMap k v -> [(k, v)]
LH.toList HashMap Text (Command m c a, AliasType)
commands) (HashMap Text (Group m c a, AliasType)
-> [(Text, (Group m c a, AliasType))]
forall (k :: OpticKind) (v :: OpticKind). HashMap k v -> [(k, v)]
LH.toList HashMap Text (Group m c a, AliasType)
children) Bool
hidden