{-# LANGUAGE NoPolyKinds #-}

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

import CalamityCommands.AliasType
import CalamityCommands.Check
import {-# SOURCE #-} CalamityCommands.Command

import Control.Lens hiding (Context, (<.>))

import qualified Data.HashMap.Lazy as LH
import qualified Data.Text as S
import qualified Data.Text.Lazy as L

import GHC.Generics

import Data.List.NonEmpty (NonEmpty)
import qualified Data.List.NonEmpty as NE
import TextShow
import qualified TextShow.Generic as TSG

-- | A group of commands
data Group m c a = Group
    { Group m c a -> NonEmpty Text
names :: NonEmpty S.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 S.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 S.Text (Group m c a, AliasType)
    , -- | A function producing the \'help\' for the group
      Group m c a -> c -> Text
help :: c -> L.Text
    , -- | A list of checks that must pass
      Group m c a -> [Check m c]
checks :: [Check m c]
    }
    deriving ((forall x. Group m c a -> Rep (Group m c a) x)
-> (forall x. Rep (Group m c a) x -> Group m c a)
-> Generic (Group m c a)
forall x. Rep (Group m c a) x -> Group m c a
forall x. Group m c a -> Rep (Group m c a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (m :: * -> *) c a x. Rep (Group m c a) x -> Group m c a
forall (m :: * -> *) c a x. Group m c a -> Rep (Group m c a) x
$cto :: forall (m :: * -> *) c a x. Rep (Group m c a) x -> Group m c a
$cfrom :: forall (m :: * -> *) c a x. Group m c a -> Rep (Group m c a) x
Generic)

data GroupS m c a = GroupS
    { GroupS m c a -> NonEmpty Text
names :: NonEmpty S.Text
    , GroupS m c a -> Maybe Text
parent :: Maybe S.Text
    , GroupS m c a -> [(Text, (Command m c a, AliasType))]
commands :: [(S.Text, (Command m c a, AliasType))]
    , GroupS m c a -> [(Text, (Group m c a, AliasType))]
children :: [(S.Text, (Group m c a, AliasType))]
    , GroupS m c a -> Bool
hidden :: Bool
    }
    deriving ((forall x. GroupS m c a -> Rep (GroupS m c a) x)
-> (forall x. Rep (GroupS m c a) x -> GroupS m c a)
-> Generic (GroupS m c a)
forall x. Rep (GroupS m c a) x -> GroupS m c a
forall x. GroupS m c a -> Rep (GroupS m c a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (m :: * -> *) c a x. Rep (GroupS m c a) x -> GroupS m c a
forall (m :: * -> *) c a x. GroupS m c a -> Rep (GroupS m c a) x
$cto :: forall (m :: * -> *) c a x. Rep (GroupS m c a) x -> GroupS m c a
$cfrom :: forall (m :: * -> *) c a x. GroupS m c a -> Rep (GroupS m c a) x
Generic, 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.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (m :: * -> *) c a. Int -> GroupS m c a -> ShowS
forall (m :: * -> *) c a. [GroupS m c a] -> ShowS
forall (m :: * -> *) c a. GroupS m c a -> String
showList :: [GroupS m c a] -> ShowS
$cshowList :: forall (m :: * -> *) c a. [GroupS m c a] -> ShowS
show :: GroupS m c a -> String
$cshow :: forall (m :: * -> *) c a. GroupS m c a -> String
showsPrec :: Int -> GroupS m c a -> ShowS
$cshowsPrec :: forall (m :: * -> *) c a. Int -> GroupS m c a -> ShowS
Show)
    deriving (Int -> GroupS m c a -> Builder
Int -> GroupS m c a -> Text
Int -> GroupS m c a -> Text
[GroupS m c a] -> Builder
[GroupS m c a] -> Text
[GroupS m c a] -> Text
GroupS m c a -> Builder
GroupS m c a -> Text
GroupS m c a -> Text
(Int -> GroupS m c a -> Builder)
-> (GroupS m c a -> Builder)
-> ([GroupS m c a] -> Builder)
-> (Int -> GroupS m c a -> Text)
-> (GroupS m c a -> Text)
-> ([GroupS m c a] -> Text)
-> (Int -> GroupS m c a -> Text)
-> (GroupS m c a -> Text)
-> ([GroupS m c a] -> Text)
-> TextShow (GroupS m c a)
forall a.
(Int -> a -> Builder)
-> (a -> Builder)
-> ([a] -> Builder)
-> (Int -> a -> Text)
-> (a -> Text)
-> ([a] -> Text)
-> (Int -> a -> Text)
-> (a -> Text)
-> ([a] -> Text)
-> TextShow a
forall (m :: * -> *) c a. Int -> GroupS m c a -> Builder
forall (m :: * -> *) c a. Int -> GroupS m c a -> Text
forall (m :: * -> *) c a. Int -> GroupS m c a -> Text
forall (m :: * -> *) c a. [GroupS m c a] -> Builder
forall (m :: * -> *) c a. [GroupS m c a] -> Text
forall (m :: * -> *) c a. [GroupS m c a] -> Text
forall (m :: * -> *) c a. GroupS m c a -> Builder
forall (m :: * -> *) c a. GroupS m c a -> Text
forall (m :: * -> *) c a. GroupS m c a -> Text
showtlList :: [GroupS m c a] -> Text
$cshowtlList :: forall (m :: * -> *) c a. [GroupS m c a] -> Text
showtl :: GroupS m c a -> Text
$cshowtl :: forall (m :: * -> *) c a. GroupS m c a -> Text
showtlPrec :: Int -> GroupS m c a -> Text
$cshowtlPrec :: forall (m :: * -> *) c a. Int -> GroupS m c a -> Text
showtList :: [GroupS m c a] -> Text
$cshowtList :: forall (m :: * -> *) c a. [GroupS m c a] -> Text
showt :: GroupS m c a -> Text
$cshowt :: forall (m :: * -> *) c a. GroupS m c a -> Text
showtPrec :: Int -> GroupS m c a -> Text
$cshowtPrec :: forall (m :: * -> *) c a. Int -> GroupS m c a -> Text
showbList :: [GroupS m c a] -> Builder
$cshowbList :: forall (m :: * -> *) c a. [GroupS m c a] -> Builder
showb :: GroupS m c a -> Builder
$cshowb :: forall (m :: * -> *) c a. GroupS m c a -> Builder
showbPrec :: Int -> GroupS m c a -> Builder
$cshowbPrec :: forall (m :: * -> *) c a. Int -> GroupS m c a -> Builder
TextShow) via TSG.FromGeneric (GroupS m c a)

instance 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 :: * -> *) c a. Group m c a -> NonEmpty Text
names, Maybe (Group m c a)
parent :: Maybe (Group m c a)
$sel:parent:Group :: forall (m :: * -> *) c a. 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 :: * -> *) c a.
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 :: * -> *) c a.
Group m c a -> HashMap Text (Group m c a, AliasType)
children, Bool
hidden :: Bool
$sel:hidden:Group :: forall (m :: * -> *) c a. Group m c a -> Bool
hidden} =
        Int -> GroupS m c a -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
d (GroupS m c a -> ShowS) -> GroupS m c a -> ShowS
forall a 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 :: * -> *) c a.
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. NonEmpty a -> a
NE.head (NonEmpty Text -> Text) -> Maybe (NonEmpty Text) -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (Group m c a)
parent Maybe (Group m c a)
-> Getting
     (First (NonEmpty Text)) (Maybe (Group m c a)) (NonEmpty Text)
-> Maybe (NonEmpty Text)
forall s a. s -> Getting (First a) s a -> Maybe a
^? (Group m c a -> Const (First (NonEmpty Text)) (Group m c a))
-> Maybe (Group m c a)
-> Const (First (NonEmpty Text)) (Maybe (Group m c a))
forall a b. Prism (Maybe a) (Maybe b) a b
_Just ((Group m c a -> Const (First (NonEmpty Text)) (Group m c a))
 -> Maybe (Group m c a)
 -> Const (First (NonEmpty Text)) (Maybe (Group m c a)))
-> ((NonEmpty Text
     -> Const (First (NonEmpty Text)) (NonEmpty Text))
    -> Group m c a -> Const (First (NonEmpty Text)) (Group m c a))
-> Getting
     (First (NonEmpty Text)) (Maybe (Group m c a)) (NonEmpty Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IsLabel
  "names"
  ((NonEmpty Text -> Const (First (NonEmpty Text)) (NonEmpty Text))
   -> Group m c a -> Const (First (NonEmpty Text)) (Group m c a))
(NonEmpty Text -> Const (First (NonEmpty Text)) (NonEmpty Text))
-> Group m c a -> Const (First (NonEmpty Text)) (Group m c a)
#names) (HashMap Text (Command m c a, AliasType)
-> [(Text, (Command m c a, AliasType))]
forall k v. 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 v. HashMap k v -> [(k, v)]
LH.toList HashMap Text (Group m c a, AliasType)
children) Bool
hidden

instance 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 :: * -> *) c a. Group m c a -> NonEmpty Text
names, Maybe (Group m c a)
parent :: Maybe (Group m c a)
$sel:parent:Group :: forall (m :: * -> *) c a. 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 :: * -> *) c a.
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 :: * -> *) c a.
Group m c a -> HashMap Text (Group m c a, AliasType)
children, Bool
hidden :: Bool
$sel:hidden:Group :: forall (m :: * -> *) c a. Group m c a -> Bool
hidden} =
      Int -> GroupS m c a -> Builder
forall a. TextShow a => Int -> a -> Builder
showbPrec Int
d (GroupS m c a -> Builder) -> GroupS m c a -> Builder
forall a 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 :: * -> *) c a.
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. NonEmpty a -> a
NE.head (NonEmpty Text -> Text) -> Maybe (NonEmpty Text) -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (Group m c a)
parent Maybe (Group m c a)
-> Getting
     (First (NonEmpty Text)) (Maybe (Group m c a)) (NonEmpty Text)
-> Maybe (NonEmpty Text)
forall s a. s -> Getting (First a) s a -> Maybe a
^? (Group m c a -> Const (First (NonEmpty Text)) (Group m c a))
-> Maybe (Group m c a)
-> Const (First (NonEmpty Text)) (Maybe (Group m c a))
forall a b. Prism (Maybe a) (Maybe b) a b
_Just ((Group m c a -> Const (First (NonEmpty Text)) (Group m c a))
 -> Maybe (Group m c a)
 -> Const (First (NonEmpty Text)) (Maybe (Group m c a)))
-> ((NonEmpty Text
     -> Const (First (NonEmpty Text)) (NonEmpty Text))
    -> Group m c a -> Const (First (NonEmpty Text)) (Group m c a))
-> Getting
     (First (NonEmpty Text)) (Maybe (Group m c a)) (NonEmpty Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IsLabel
  "names"
  ((NonEmpty Text -> Const (First (NonEmpty Text)) (NonEmpty Text))
   -> Group m c a -> Const (First (NonEmpty Text)) (Group m c a))
(NonEmpty Text -> Const (First (NonEmpty Text)) (NonEmpty Text))
-> Group m c a -> Const (First (NonEmpty Text)) (Group m c a)
#names) (HashMap Text (Command m c a, AliasType)
-> [(Text, (Command m c a, AliasType))]
forall k v. 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 v. HashMap k v -> [(k, v)]
LH.toList HashMap Text (Group m c a, AliasType)
children) Bool
hidden