{-# LANGUAGE TemplateHaskell #-}

-- | The generic guild channel type
module Calamity.Types.Model.Channel.Guild (
  GuildChannel (..),
  module Calamity.Types.Model.Channel.Guild.Category,
  module Calamity.Types.Model.Channel.Guild.Text,
  module Calamity.Types.Model.Channel.Guild.Voice,
) where

import {-# SOURCE #-} Calamity.Types.Model.Channel
import Calamity.Types.Model.Channel.ChannelType
import Calamity.Types.Model.Channel.Guild.Category
import Calamity.Types.Model.Channel.Guild.Text
import Calamity.Types.Model.Channel.Guild.Voice
import {-# SOURCE #-} Calamity.Types.Model.Guild.Guild
import Calamity.Types.Snowflake
import Data.Aeson ((.:))
import qualified Data.Aeson as Aeson
import Optics ((^.))
import Optics.TH
import TextShow.TH

data GuildChannel
  = GuildTextChannel TextChannel
  | GuildVoiceChannel VoiceChannel
  | GuildCategory Category
  | OtherGuildChannel (Snowflake Guild) (Snowflake GuildChannel) -- TODO
  deriving (Int -> GuildChannel -> ShowS
[GuildChannel] -> ShowS
GuildChannel -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [GuildChannel] -> ShowS
$cshowList :: [GuildChannel] -> ShowS
show :: GuildChannel -> String
$cshow :: GuildChannel -> String
showsPrec :: Int -> GuildChannel -> ShowS
$cshowsPrec :: Int -> GuildChannel -> ShowS
Show, GuildChannel -> GuildChannel -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GuildChannel -> GuildChannel -> Bool
$c/= :: GuildChannel -> GuildChannel -> Bool
== :: GuildChannel -> GuildChannel -> Bool
$c== :: GuildChannel -> GuildChannel -> Bool
Eq)

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

    case ChannelType
type_ of
      ChannelType
GuildTextType -> TextChannel -> GuildChannel
GuildTextChannel 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 -> VoiceChannel -> GuildChannel
GuildVoiceChannel 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 -> Category -> GuildChannel
GuildCategory 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
_typ -> do
        Snowflake GuildChannel
id_ <- Object
v forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"id"
        Snowflake Guild
guildID <- Object
v forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"guild_id"
        forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Snowflake Guild -> Snowflake GuildChannel -> GuildChannel
OtherGuildChannel Snowflake Guild
guildID Snowflake GuildChannel
id_

instance HasID GuildChannel GuildChannel where
  getID :: GuildChannel -> Snowflake GuildChannel
getID (GuildTextChannel TextChannel
a) = forall a b. Snowflake a -> Snowflake b
coerceSnowflake forall a b. (a -> b) -> a -> b
$ TextChannel
a forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. forall a. IsLabel "id" a => a
#id
  getID (GuildVoiceChannel VoiceChannel
a) = forall a b. Snowflake a -> Snowflake b
coerceSnowflake forall a b. (a -> b) -> a -> b
$ VoiceChannel
a forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. forall a. IsLabel "id" a => a
#id
  getID (GuildCategory Category
a) = forall a b. Snowflake a -> Snowflake b
coerceSnowflake forall a b. (a -> b) -> a -> b
$ Category
a forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. forall a. IsLabel "id" a => a
#id
  getID (OtherGuildChannel Snowflake Guild
_ Snowflake GuildChannel
a) = Snowflake GuildChannel
a

instance HasID Channel GuildChannel where
  getID :: GuildChannel -> Snowflake Channel
getID = forall a b. Snowflake a -> Snowflake b
coerceSnowflake forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b a. HasID b a => a -> Snowflake b
getID @GuildChannel

instance HasID Guild GuildChannel where
  getID :: GuildChannel -> Snowflake Guild
getID (GuildTextChannel TextChannel
a) = forall a b. Snowflake a -> Snowflake b
coerceSnowflake forall a b. (a -> b) -> a -> b
$ TextChannel
a forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. forall a. IsLabel "guildID" a => a
#guildID
  getID (GuildVoiceChannel VoiceChannel
a) = forall a b. Snowflake a -> Snowflake b
coerceSnowflake forall a b. (a -> b) -> a -> b
$ VoiceChannel
a forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. forall a. IsLabel "guildID" a => a
#guildID
  getID (GuildCategory Category
a) = forall a b. Snowflake a -> Snowflake b
coerceSnowflake forall a b. (a -> b) -> a -> b
$ Category
a forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. forall a. IsLabel "guildID" a => a
#guildID
  getID (OtherGuildChannel Snowflake Guild
a Snowflake GuildChannel
_) = Snowflake Guild
a

$(deriveTextShow ''GuildChannel)
$(makeFieldLabelsNoPrefix ''GuildChannel)