-- | A message from a channel
module Calamity.Types.Model.Channel.Message (
  Message (..),
  MessageType (..),
  MessageReference (..),
) where

import Calamity.Internal.AesonThings
import Calamity.Internal.Utils ()
import {-# SOURCE #-} Calamity.Types.Model.Channel
import Calamity.Types.Model.Channel.Attachment
import Calamity.Types.Model.Channel.Embed
import Calamity.Types.Model.Channel.Reaction
import Calamity.Types.Model.Channel.Webhook
import {-# SOURCE #-} Calamity.Types.Model.Guild.Guild
import Calamity.Types.Model.Guild.Role
import Calamity.Types.Model.User
import Calamity.Types.Snowflake

import Data.Aeson
import Data.Scientific
import Data.Text.Lazy (Text)
import Data.Time
import qualified Data.Vector.Unboxing as UV

import GHC.Generics

import Data.Word (Word64)
import TextShow
import qualified TextShow.Generic as TSG

data Message = Message
  { Message -> Snowflake Message
id :: Snowflake Message
  , Message -> Snowflake Channel
channelID :: Snowflake Channel
  , Message -> Maybe (Snowflake Guild)
guildID :: Maybe (Snowflake Guild)
  , Message -> Snowflake User
author :: Snowflake User
  , Message -> Text
content :: Text
  , Message -> UTCTime
timestamp :: UTCTime
  , Message -> Maybe UTCTime
editedTimestamp :: Maybe UTCTime
  , Message -> Bool
tts :: Bool
  , Message -> Bool
mentionEveryone :: Bool
  , Message -> Vector (Snowflake User)
mentions :: UV.Vector (Snowflake User)
  , Message -> Vector (Snowflake Role)
mentionRoles :: UV.Vector (Snowflake Role)
  , Message -> Maybe (Vector (Snowflake Channel))
mentionChannels :: Maybe (UV.Vector (Snowflake Channel))
  , Message -> [Attachment]
attachments :: ![Attachment]
  , Message -> [Embed]
embeds :: ![Embed]
  , Message -> [Reaction]
reactions :: ![Reaction]
  , Message -> Maybe (Snowflake Message)
nonce :: Maybe (Snowflake Message)
  , Message -> Bool
pinned :: Bool
  , Message -> Maybe (Snowflake Webhook)
webhookID :: Maybe (Snowflake Webhook)
  , Message -> MessageType
type_ :: !MessageType
  , Message -> Maybe Object
activity :: Maybe Object
  , Message -> Maybe Object
application :: Maybe Object
  , Message -> Maybe MessageReference
messageReference :: Maybe MessageReference
  , Message -> Word64
flags :: Word64
  , Message -> Maybe [Object]
stickers :: Maybe [Object]
  , Message -> Maybe Message
referencedMessage :: Maybe Message
  , Message -> Maybe Object
interaction :: Maybe Object
  }
  deriving (Message -> Message -> Bool
(Message -> Message -> Bool)
-> (Message -> Message -> Bool) -> Eq Message
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Message -> Message -> Bool
$c/= :: Message -> Message -> Bool
== :: Message -> Message -> Bool
$c== :: Message -> Message -> Bool
Eq, Int -> Message -> ShowS
[Message] -> ShowS
Message -> String
(Int -> Message -> ShowS)
-> (Message -> String) -> ([Message] -> ShowS) -> Show Message
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Message] -> ShowS
$cshowList :: [Message] -> ShowS
show :: Message -> String
$cshow :: Message -> String
showsPrec :: Int -> Message -> ShowS
$cshowsPrec :: Int -> Message -> ShowS
Show, (forall x. Message -> Rep Message x)
-> (forall x. Rep Message x -> Message) -> Generic Message
forall x. Rep Message x -> Message
forall x. Message -> Rep Message x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Message x -> Message
$cfrom :: forall x. Message -> Rep Message x
Generic)
  deriving (Int -> Message -> Builder
Int -> Message -> Text
Int -> Message -> Text
[Message] -> Builder
[Message] -> Text
[Message] -> Text
Message -> Builder
Message -> Text
Message -> Text
(Int -> Message -> Builder)
-> (Message -> Builder)
-> ([Message] -> Builder)
-> (Int -> Message -> Text)
-> (Message -> Text)
-> ([Message] -> Text)
-> (Int -> Message -> Text)
-> (Message -> Text)
-> ([Message] -> Text)
-> TextShow Message
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
showtlList :: [Message] -> Text
$cshowtlList :: [Message] -> Text
showtl :: Message -> Text
$cshowtl :: Message -> Text
showtlPrec :: Int -> Message -> Text
$cshowtlPrec :: Int -> Message -> Text
showtList :: [Message] -> Text
$cshowtList :: [Message] -> Text
showt :: Message -> Text
$cshowt :: Message -> Text
showtPrec :: Int -> Message -> Text
$cshowtPrec :: Int -> Message -> Text
showbList :: [Message] -> Builder
$cshowbList :: [Message] -> Builder
showb :: Message -> Builder
$cshowb :: Message -> Builder
showbPrec :: Int -> Message -> Builder
$cshowbPrec :: Int -> Message -> Builder
TextShow) via TSG.FromGeneric Message
  deriving
    (Value -> Parser [Message]
Value -> Parser Message
(Value -> Parser Message)
-> (Value -> Parser [Message]) -> FromJSON Message
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [Message]
$cparseJSONList :: Value -> Parser [Message]
parseJSON :: Value -> Parser Message
$cparseJSON :: Value -> Parser Message
FromJSON)
    via WithSpecialCases
          '[ "author" `ExtractFieldFrom` "id"
           , "mentions" `ExtractArrayField` "id"
           , "mention_channels" `ExtractArrayField` "id"
           , "reactions" `IfNoneThen` DefaultToEmptyArray
           ]
          Message
  deriving (HasID Message) via HasIDField "id" Message
  deriving (HasID Channel) via HasIDField "channelID" Message
  deriving (HasID User) via HasIDField "author" Message

data MessageReference = MessageReference
  { MessageReference -> Maybe (Snowflake Message)
messageID :: Maybe (Snowflake Message)
  , MessageReference -> Maybe (Snowflake Channel)
channelID :: Maybe (Snowflake Channel)
  , MessageReference -> Maybe (Snowflake Guild)
guildID :: Maybe (Snowflake Guild)
  , MessageReference -> Bool
failIfNotExists :: Bool
  }
  deriving (MessageReference -> MessageReference -> Bool
(MessageReference -> MessageReference -> Bool)
-> (MessageReference -> MessageReference -> Bool)
-> Eq MessageReference
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MessageReference -> MessageReference -> Bool
$c/= :: MessageReference -> MessageReference -> Bool
== :: MessageReference -> MessageReference -> Bool
$c== :: MessageReference -> MessageReference -> Bool
Eq, Int -> MessageReference -> ShowS
[MessageReference] -> ShowS
MessageReference -> String
(Int -> MessageReference -> ShowS)
-> (MessageReference -> String)
-> ([MessageReference] -> ShowS)
-> Show MessageReference
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MessageReference] -> ShowS
$cshowList :: [MessageReference] -> ShowS
show :: MessageReference -> String
$cshow :: MessageReference -> String
showsPrec :: Int -> MessageReference -> ShowS
$cshowsPrec :: Int -> MessageReference -> ShowS
Show, (forall x. MessageReference -> Rep MessageReference x)
-> (forall x. Rep MessageReference x -> MessageReference)
-> Generic MessageReference
forall x. Rep MessageReference x -> MessageReference
forall x. MessageReference -> Rep MessageReference x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep MessageReference x -> MessageReference
$cfrom :: forall x. MessageReference -> Rep MessageReference x
Generic)
  deriving (Int -> MessageReference -> Builder
Int -> MessageReference -> Text
Int -> MessageReference -> Text
[MessageReference] -> Builder
[MessageReference] -> Text
[MessageReference] -> Text
MessageReference -> Builder
MessageReference -> Text
MessageReference -> Text
(Int -> MessageReference -> Builder)
-> (MessageReference -> Builder)
-> ([MessageReference] -> Builder)
-> (Int -> MessageReference -> Text)
-> (MessageReference -> Text)
-> ([MessageReference] -> Text)
-> (Int -> MessageReference -> Text)
-> (MessageReference -> Text)
-> ([MessageReference] -> Text)
-> TextShow MessageReference
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
showtlList :: [MessageReference] -> Text
$cshowtlList :: [MessageReference] -> Text
showtl :: MessageReference -> Text
$cshowtl :: MessageReference -> Text
showtlPrec :: Int -> MessageReference -> Text
$cshowtlPrec :: Int -> MessageReference -> Text
showtList :: [MessageReference] -> Text
$cshowtList :: [MessageReference] -> Text
showt :: MessageReference -> Text
$cshowt :: MessageReference -> Text
showtPrec :: Int -> MessageReference -> Text
$cshowtPrec :: Int -> MessageReference -> Text
showbList :: [MessageReference] -> Builder
$cshowbList :: [MessageReference] -> Builder
showb :: MessageReference -> Builder
$cshowb :: MessageReference -> Builder
showbPrec :: Int -> MessageReference -> Builder
$cshowbPrec :: Int -> MessageReference -> Builder
TextShow) via TSG.FromGeneric MessageReference
  deriving
    (Value -> Parser [MessageReference]
Value -> Parser MessageReference
(Value -> Parser MessageReference)
-> (Value -> Parser [MessageReference])
-> FromJSON MessageReference
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [MessageReference]
$cparseJSONList :: Value -> Parser [MessageReference]
parseJSON :: Value -> Parser MessageReference
$cparseJSON :: Value -> Parser MessageReference
FromJSON)
    via WithSpecialCases
          '[ "fail_if_not_exists" `IfNoneThen` DefaultToTrue
           ]
          MessageReference
  deriving ([MessageReference] -> Encoding
[MessageReference] -> Value
MessageReference -> Encoding
MessageReference -> Value
(MessageReference -> Value)
-> (MessageReference -> Encoding)
-> ([MessageReference] -> Value)
-> ([MessageReference] -> Encoding)
-> ToJSON MessageReference
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [MessageReference] -> Encoding
$ctoEncodingList :: [MessageReference] -> Encoding
toJSONList :: [MessageReference] -> Value
$ctoJSONList :: [MessageReference] -> Value
toEncoding :: MessageReference -> Encoding
$ctoEncoding :: MessageReference -> Encoding
toJSON :: MessageReference -> Value
$ctoJSON :: MessageReference -> Value
ToJSON) via CalamityJSON MessageReference

-- Thanks sbrg (https://github.com/saevarb/haskord/blob/d1bb07bcc4f3dbc29f2dfd3351ff9f16fc100c07/haskord-lib/src/Haskord/Types/Common.hs#L264)
data MessageType
  = Default
  | RecipientAdd
  | RecipientRemove
  | Call
  | ChannelNameChange
  | ChannelIconChange
  | ChannelPinnedMessage
  | GuildMemberJoin
  | UserPremiumGuildSubscription
  | UserPremiumGuildSubscriptionTier1
  | UserPremiumGuildSubscriptionTier2
  | UserPremiumGuildSubscriptionTier3
  | ChannelFollowAdd
  | GuildDiscoveryDisqualified
  | GuildDiscoveryRequalified
  | Reply
  | ApplicationCommmand
  deriving (MessageType -> MessageType -> Bool
(MessageType -> MessageType -> Bool)
-> (MessageType -> MessageType -> Bool) -> Eq MessageType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MessageType -> MessageType -> Bool
$c/= :: MessageType -> MessageType -> Bool
== :: MessageType -> MessageType -> Bool
$c== :: MessageType -> MessageType -> Bool
Eq, Int -> MessageType -> ShowS
[MessageType] -> ShowS
MessageType -> String
(Int -> MessageType -> ShowS)
-> (MessageType -> String)
-> ([MessageType] -> ShowS)
-> Show MessageType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MessageType] -> ShowS
$cshowList :: [MessageType] -> ShowS
show :: MessageType -> String
$cshow :: MessageType -> String
showsPrec :: Int -> MessageType -> ShowS
$cshowsPrec :: Int -> MessageType -> ShowS
Show, Int -> MessageType
MessageType -> Int
MessageType -> [MessageType]
MessageType -> MessageType
MessageType -> MessageType -> [MessageType]
MessageType -> MessageType -> MessageType -> [MessageType]
(MessageType -> MessageType)
-> (MessageType -> MessageType)
-> (Int -> MessageType)
-> (MessageType -> Int)
-> (MessageType -> [MessageType])
-> (MessageType -> MessageType -> [MessageType])
-> (MessageType -> MessageType -> [MessageType])
-> (MessageType -> MessageType -> MessageType -> [MessageType])
-> Enum MessageType
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: MessageType -> MessageType -> MessageType -> [MessageType]
$cenumFromThenTo :: MessageType -> MessageType -> MessageType -> [MessageType]
enumFromTo :: MessageType -> MessageType -> [MessageType]
$cenumFromTo :: MessageType -> MessageType -> [MessageType]
enumFromThen :: MessageType -> MessageType -> [MessageType]
$cenumFromThen :: MessageType -> MessageType -> [MessageType]
enumFrom :: MessageType -> [MessageType]
$cenumFrom :: MessageType -> [MessageType]
fromEnum :: MessageType -> Int
$cfromEnum :: MessageType -> Int
toEnum :: Int -> MessageType
$ctoEnum :: Int -> MessageType
pred :: MessageType -> MessageType
$cpred :: MessageType -> MessageType
succ :: MessageType -> MessageType
$csucc :: MessageType -> MessageType
Enum, (forall x. MessageType -> Rep MessageType x)
-> (forall x. Rep MessageType x -> MessageType)
-> Generic MessageType
forall x. Rep MessageType x -> MessageType
forall x. MessageType -> Rep MessageType x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep MessageType x -> MessageType
$cfrom :: forall x. MessageType -> Rep MessageType x
Generic)
  deriving (Int -> MessageType -> Builder
Int -> MessageType -> Text
Int -> MessageType -> Text
[MessageType] -> Builder
[MessageType] -> Text
[MessageType] -> Text
MessageType -> Builder
MessageType -> Text
MessageType -> Text
(Int -> MessageType -> Builder)
-> (MessageType -> Builder)
-> ([MessageType] -> Builder)
-> (Int -> MessageType -> Text)
-> (MessageType -> Text)
-> ([MessageType] -> Text)
-> (Int -> MessageType -> Text)
-> (MessageType -> Text)
-> ([MessageType] -> Text)
-> TextShow MessageType
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
showtlList :: [MessageType] -> Text
$cshowtlList :: [MessageType] -> Text
showtl :: MessageType -> Text
$cshowtl :: MessageType -> Text
showtlPrec :: Int -> MessageType -> Text
$cshowtlPrec :: Int -> MessageType -> Text
showtList :: [MessageType] -> Text
$cshowtList :: [MessageType] -> Text
showt :: MessageType -> Text
$cshowt :: MessageType -> Text
showtPrec :: Int -> MessageType -> Text
$cshowtPrec :: Int -> MessageType -> Text
showbList :: [MessageType] -> Builder
$cshowbList :: [MessageType] -> Builder
showb :: MessageType -> Builder
$cshowb :: MessageType -> Builder
showbPrec :: Int -> MessageType -> Builder
$cshowbPrec :: Int -> MessageType -> Builder
TextShow) via TSG.FromGeneric MessageType

instance FromJSON MessageType where
  parseJSON :: Value -> Parser MessageType
parseJSON = String
-> (Scientific -> Parser MessageType)
-> Value
-> Parser MessageType
forall a. String -> (Scientific -> Parser a) -> Value -> Parser a
withScientific String
"MessageType" ((Scientific -> Parser MessageType) -> Value -> Parser MessageType)
-> (Scientific -> Parser MessageType)
-> Value
-> Parser MessageType
forall a b. (a -> b) -> a -> b
$ \Scientific
n -> case Scientific -> Maybe Int
forall i. (Integral i, Bounded i) => Scientific -> Maybe i
toBoundedInteger @Int Scientific
n of
    Just !Int
v -> case Int
v of
      Int
0 -> MessageType -> Parser MessageType
forall (f :: * -> *) a. Applicative f => a -> f a
pure MessageType
Default
      Int
1 -> MessageType -> Parser MessageType
forall (f :: * -> *) a. Applicative f => a -> f a
pure MessageType
RecipientAdd
      Int
2 -> MessageType -> Parser MessageType
forall (f :: * -> *) a. Applicative f => a -> f a
pure MessageType
RecipientRemove
      Int
3 -> MessageType -> Parser MessageType
forall (f :: * -> *) a. Applicative f => a -> f a
pure MessageType
Call
      Int
4 -> MessageType -> Parser MessageType
forall (f :: * -> *) a. Applicative f => a -> f a
pure MessageType
ChannelNameChange
      Int
5 -> MessageType -> Parser MessageType
forall (f :: * -> *) a. Applicative f => a -> f a
pure MessageType
ChannelIconChange
      Int
6 -> MessageType -> Parser MessageType
forall (f :: * -> *) a. Applicative f => a -> f a
pure MessageType
ChannelPinnedMessage
      Int
7 -> MessageType -> Parser MessageType
forall (f :: * -> *) a. Applicative f => a -> f a
pure MessageType
GuildMemberJoin
      Int
8 -> MessageType -> Parser MessageType
forall (f :: * -> *) a. Applicative f => a -> f a
pure MessageType
UserPremiumGuildSubscription
      Int
9 -> MessageType -> Parser MessageType
forall (f :: * -> *) a. Applicative f => a -> f a
pure MessageType
UserPremiumGuildSubscriptionTier1
      Int
10 -> MessageType -> Parser MessageType
forall (f :: * -> *) a. Applicative f => a -> f a
pure MessageType
UserPremiumGuildSubscriptionTier2
      Int
11 -> MessageType -> Parser MessageType
forall (f :: * -> *) a. Applicative f => a -> f a
pure MessageType
UserPremiumGuildSubscriptionTier3
      Int
12 -> MessageType -> Parser MessageType
forall (f :: * -> *) a. Applicative f => a -> f a
pure MessageType
ChannelFollowAdd
      Int
14 -> MessageType -> Parser MessageType
forall (f :: * -> *) a. Applicative f => a -> f a
pure MessageType
GuildDiscoveryDisqualified
      Int
15 -> MessageType -> Parser MessageType
forall (f :: * -> *) a. Applicative f => a -> f a
pure MessageType
GuildDiscoveryRequalified
      Int
19 -> MessageType -> Parser MessageType
forall (f :: * -> *) a. Applicative f => a -> f a
pure MessageType
Reply
      Int
20 -> MessageType -> Parser MessageType
forall (f :: * -> *) a. Applicative f => a -> f a
pure MessageType
ApplicationCommmand
      Int
_ -> String -> Parser MessageType
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser MessageType) -> String -> Parser MessageType
forall a b. (a -> b) -> a -> b
$ String
"Invalid MessageType: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Scientific -> String
forall a. Show a => a -> String
show Scientific
n
    Maybe Int
Nothing -> String -> Parser MessageType
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser MessageType) -> String -> Parser MessageType
forall a b. (a -> b) -> a -> b
$ String
"Invalid MessageType: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Scientific -> String
forall a. Show a => a -> String
show Scientific
n