{-# LANGUAGE TemplateHaskell #-}

-- | The generic channel type
module Calamity.Types.Model.Channel (
  Channel (..),
  Partial (PartialChannel),
  module Calamity.Types.Model.Channel.DM,
  module Calamity.Types.Model.Channel.Group,
  module Calamity.Types.Model.Channel.Guild,
  module Calamity.Types.Model.Channel.Attachment,
  module Calamity.Types.Model.Channel.Reaction,
  module Calamity.Types.Model.Channel.Webhook,
  module Calamity.Types.Model.Channel.Embed,
  module Calamity.Types.Model.Channel.ChannelType,
  module Calamity.Types.Model.Channel.Message,
  module Calamity.Types.Model.Channel.Component,
) where

import Calamity.Internal.Utils
import Calamity.Types.Model.Channel.Attachment
import Calamity.Types.Model.Channel.ChannelType
import Calamity.Types.Model.Channel.Component
import Calamity.Types.Model.Channel.DM
import Calamity.Types.Model.Channel.Embed
import Calamity.Types.Model.Channel.Group
import Calamity.Types.Model.Channel.Guild
import Calamity.Types.Model.Channel.Message
import Calamity.Types.Model.Channel.Reaction
import Calamity.Types.Model.Channel.Webhook
import Calamity.Types.Model.Guild.Permissions (Permissions)
import Calamity.Types.Snowflake
import Data.Aeson ((.:), (.:?))
import qualified Data.Aeson as Aeson
import Data.Text (Text)
import Optics.TH
import TextShow.TH

data Channel
  = DMChannel' DMChannel
  | GroupChannel' GroupChannel
  | GuildChannel' GuildChannel
  deriving (Int -> Channel -> ShowS
[Channel] -> ShowS
Channel -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Channel] -> ShowS
$cshowList :: [Channel] -> ShowS
show :: Channel -> String
$cshow :: Channel -> String
showsPrec :: Int -> Channel -> ShowS
$cshowsPrec :: Int -> Channel -> ShowS
Show, Channel -> Channel -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Channel -> Channel -> Bool
$c/= :: Channel -> Channel -> Bool
== :: Channel -> Channel -> Bool
$c== :: Channel -> Channel -> Bool
Eq)

instance HasID Channel Channel where
  getID :: Channel -> Snowflake Channel
getID (DMChannel' DMChannel
a) = forall b a. HasID b a => a -> Snowflake b
getID DMChannel
a
  getID (GroupChannel' GroupChannel
a) = forall b a. HasID b a => a -> Snowflake b
getID GroupChannel
a
  getID (GuildChannel' GuildChannel
a) = forall b a. HasID b a => a -> Snowflake b
getID GuildChannel
a

instance Aeson.FromJSON Channel where
  parseJSON :: Value -> Parser Channel
parseJSON = forall a. String -> (Object -> Parser a) -> Value -> Parser a
Aeson.withObject String
"Channel" forall a b. (a -> b) -> a -> b
$ \Object
v -> do
    ChannelType
type_ <- Object
v forall a. FromJSON a => Object -> Key -> Parser a
Aeson..: Key
"type"

    case ChannelType
type_ of
      ChannelType
GuildTextType -> GuildChannel -> Channel
GuildChannel' forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromJSON a => Value -> Parser a
Aeson.parseJSON (Object -> Value
Aeson.Object Object
v)
      ChannelType
GuildVoiceType -> GuildChannel -> Channel
GuildChannel' forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromJSON a => Value -> Parser a
Aeson.parseJSON (Object -> Value
Aeson.Object Object
v)
      ChannelType
GuildCategoryType -> GuildChannel -> Channel
GuildChannel' forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromJSON a => Value -> Parser a
Aeson.parseJSON (Object -> Value
Aeson.Object Object
v)
      ChannelType
DMType -> DMChannel -> Channel
DMChannel' forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromJSON a => Value -> Parser a
Aeson.parseJSON (Object -> Value
Aeson.Object Object
v)
      ChannelType
GroupDMType -> GroupChannel -> Channel
GroupChannel' forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromJSON a => Value -> Parser a
Aeson.parseJSON (Object -> Value
Aeson.Object Object
v)
      ChannelType
GuildNewsType -> GuildChannel -> Channel
GuildChannel' forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromJSON a => Value -> Parser a
Aeson.parseJSON (Object -> Value
Aeson.Object Object
v)
      ChannelType
GuildNewsThreadType -> GuildChannel -> Channel
GuildChannel' forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromJSON a => Value -> Parser a
Aeson.parseJSON (Object -> Value
Aeson.Object Object
v)
      ChannelType
GuildPublicThreadType -> GuildChannel -> Channel
GuildChannel' forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromJSON a => Value -> Parser a
Aeson.parseJSON (Object -> Value
Aeson.Object Object
v)
      ChannelType
GuildPrivateThreadType -> GuildChannel -> Channel
GuildChannel' forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromJSON a => Value -> Parser a
Aeson.parseJSON (Object -> Value
Aeson.Object Object
v)
      ChannelType
GuildStageVoiceType -> GuildChannel -> Channel
GuildChannel' forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromJSON a => Value -> Parser a
Aeson.parseJSON (Object -> Value
Aeson.Object Object
v)
      ChannelType
GuildDirectoryType -> GuildChannel -> Channel
GuildChannel' forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromJSON a => Value -> Parser a
Aeson.parseJSON (Object -> Value
Aeson.Object Object
v)
      ChannelType
GuildForumType -> GuildChannel -> Channel
GuildChannel' forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromJSON a => Value -> Parser a
Aeson.parseJSON (Object -> Value
Aeson.Object Object
v)

data instance Partial Channel = PartialChannel
  { Partial Channel -> Snowflake Channel
id :: Snowflake Channel
  , Partial Channel -> Text
name :: Text
  , Partial Channel -> ChannelType
type_ :: ChannelType
  , Partial Channel -> Maybe Permissions
permissions :: Maybe Permissions
  , Partial Channel -> Maybe (Snowflake Category)
parentID :: Maybe (Snowflake Category)
  }
  deriving (Int -> Partial Channel -> ShowS
[Partial Channel] -> ShowS
Partial Channel -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Partial Channel] -> ShowS
$cshowList :: [Partial Channel] -> ShowS
show :: Partial Channel -> String
$cshow :: Partial Channel -> String
showsPrec :: Int -> Partial Channel -> ShowS
$cshowsPrec :: Int -> Partial Channel -> ShowS
Show, Partial Channel -> Partial Channel -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Partial Channel -> Partial Channel -> Bool
$c/= :: Partial Channel -> Partial Channel -> Bool
== :: Partial Channel -> Partial Channel -> Bool
$c== :: Partial Channel -> Partial Channel -> Bool
Eq)
  deriving (HasID Channel) via HasIDField "id" (Partial Channel)
  deriving ([Partial Channel] -> Encoding
[Partial Channel] -> Value
Partial Channel -> Encoding
Partial Channel -> Value
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [Partial Channel] -> Encoding
$ctoEncodingList :: [Partial Channel] -> Encoding
toJSONList :: [Partial Channel] -> Value
$ctoJSONList :: [Partial Channel] -> Value
toEncoding :: Partial Channel -> Encoding
$ctoEncoding :: Partial Channel -> Encoding
toJSON :: Partial Channel -> Value
$ctoJSON :: Partial Channel -> Value
Aeson.ToJSON) via CalamityToJSON (Partial Channel)

instance CalamityToJSON' (Partial Channel) where
  toPairs :: forall kv. KeyValue kv => Partial Channel -> [Maybe kv]
toPairs PartialChannel {Maybe Permissions
Maybe (Snowflake Category)
Text
ChannelType
Snowflake Channel
parentID :: Maybe (Snowflake Category)
permissions :: Maybe Permissions
type_ :: ChannelType
name :: Text
id :: Snowflake Channel
$sel:parentID:PartialChannel :: Partial Channel -> Maybe (Snowflake Category)
$sel:permissions:PartialChannel :: Partial Channel -> Maybe Permissions
$sel:type_:PartialChannel :: Partial Channel -> ChannelType
$sel:name:PartialChannel :: Partial Channel -> Text
$sel:id:PartialChannel :: Partial Channel -> Snowflake Channel
..} =
    [ Key
"id" forall v kv. (ToJSON v, KeyValue kv) => Key -> v -> Maybe kv
.= Snowflake Channel
id
    , Key
"name" forall v kv. (ToJSON v, KeyValue kv) => Key -> v -> Maybe kv
.= Text
name
    , Key
"type" forall v kv. (ToJSON v, KeyValue kv) => Key -> v -> Maybe kv
.= ChannelType
type_
    , Key
"permissions" forall v kv. (ToJSON v, KeyValue kv) => Key -> Maybe v -> Maybe kv
.?= Maybe Permissions
permissions
    , Key
"parent_id" forall v kv. (ToJSON v, KeyValue kv) => Key -> Maybe v -> Maybe kv
.?= Maybe (Snowflake Category)
parentID
    ]

instance Aeson.FromJSON (Partial Channel) where
  parseJSON :: Value -> Parser (Partial Channel)
parseJSON = forall a. String -> (Object -> Parser a) -> Value -> Parser a
Aeson.withObject String
"Partial Channel" forall a b. (a -> b) -> a -> b
$ \Object
v ->
    Snowflake Channel
-> Text
-> ChannelType
-> Maybe Permissions
-> Maybe (Snowflake Category)
-> Partial Channel
PartialChannel
      forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
v forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"id"
      forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"name"
      forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"type"
      forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"permissions"
      forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"parent_id"

$(deriveTextShow ''Channel)
$(deriveTextShow 'PartialChannel)
$(makeFieldLabelsNoPrefix ''Channel)
$(makeFieldLabelsNoPrefix 'PartialChannel)