{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
module Telegram.Bot.API.Types.MessageOrigin where

import Data.Aeson (FromJSON (..), ToJSON (..), Value (..), (.=), (.:), (.:?), withObject)
import Data.Aeson.Types (Parser)
import Data.Text (Text)
import Data.Time.Clock.POSIX (POSIXTime)
import GHC.Generics (Generic)

import qualified Data.Text as Text

import Telegram.Bot.API.Types.Chat
import Telegram.Bot.API.Types.Common
import Telegram.Bot.API.Types.User
import Telegram.Bot.API.Internal.Utils

-- ** 'MessageOrigin'

-- | This object describes the origin of a message. It can be one of
--
-- * MessageOriginUser
-- * MessageOriginHiddenUser
-- * MessageOriginChat
-- * MessageOriginChannel
--
data MessageOrigin
  -- | The message was originally sent by a known user.
  = MessageOriginUser
      { MessageOrigin -> Text
messageOriginUserType :: Text -- ^ Type of the message origin, always “user”.
      , MessageOrigin -> POSIXTime
messageOriginUserDate :: POSIXTime -- ^ Date the message was sent originally in Unix time.
      , MessageOrigin -> User
messageOriginUserSenderUser :: User -- ^ User that sent the message originally.
      }
  -- | The message was originally sent by an unknown user.
  | MessageOriginHiddenUser
      { MessageOrigin -> Text
messageOriginHiddenUserType :: Text -- ^ Type of the message origin, always “hidden_user”.
      , MessageOrigin -> POSIXTime
messageOriginHiddenUserDate :: POSIXTime -- ^ Date the message was sent originally in Unix time.
      , MessageOrigin -> Text
messageOriginHiddenUserSenderUserName :: Text -- ^ Name of the user that sent the message originally.
      }
  -- | The message was originally sent on behalf of a chat to a group chat.
  | MessageOriginChat
      { MessageOrigin -> Text
messageOriginChatType :: Text -- ^ Type of the message origin, always “chat”.
      , MessageOrigin -> POSIXTime
messageOriginChatDate :: POSIXTime -- ^ Date the message was sent originally in Unix time.
      , MessageOrigin -> Chat
messageOriginChatSenderChat :: Chat -- ^ Chat that sent the message originally.
      , MessageOrigin -> Maybe Text
messageOriginChatAuthorSignature :: Maybe Text -- ^ For messages originally sent by an anonymous chat administrator, original message author signature.
      }
  -- | The message was originally sent to a channel chat.
  | MessageOriginChannel
      { MessageOrigin -> Text
messageOriginChannelType :: Text -- ^ Type of the message origin, always “channel”.
      , MessageOrigin -> POSIXTime
messageOriginChannelDate :: POSIXTime -- ^ Date the message was sent originally in Unix time.
      , MessageOrigin -> Chat
messageOriginChannelChat :: Chat -- ^ Channel chat to which the message was originally sent.
      , MessageOrigin -> MessageId
messageOriginChannelMessageId :: MessageId -- ^ Unique message identifier inside the chat.
      , MessageOrigin -> Maybe Text
messageOriginChannelAuthorSignature :: Maybe Text -- ^ Signature of the original post author.
      }
  deriving ((forall x. MessageOrigin -> Rep MessageOrigin x)
-> (forall x. Rep MessageOrigin x -> MessageOrigin)
-> Generic MessageOrigin
forall x. Rep MessageOrigin x -> MessageOrigin
forall x. MessageOrigin -> Rep MessageOrigin x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. MessageOrigin -> Rep MessageOrigin x
from :: forall x. MessageOrigin -> Rep MessageOrigin x
$cto :: forall x. Rep MessageOrigin x -> MessageOrigin
to :: forall x. Rep MessageOrigin x -> MessageOrigin
Generic, Int -> MessageOrigin -> ShowS
[MessageOrigin] -> ShowS
MessageOrigin -> String
(Int -> MessageOrigin -> ShowS)
-> (MessageOrigin -> String)
-> ([MessageOrigin] -> ShowS)
-> Show MessageOrigin
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MessageOrigin -> ShowS
showsPrec :: Int -> MessageOrigin -> ShowS
$cshow :: MessageOrigin -> String
show :: MessageOrigin -> String
$cshowList :: [MessageOrigin] -> ShowS
showList :: [MessageOrigin] -> ShowS
Show)

instance ToJSON   MessageOrigin where
  toJSON :: MessageOrigin -> Value
toJSON = \case
    MessageOriginUser Text
_t POSIXTime
d User
su -> Value -> [Pair] -> Value
addJsonFields
      (Object -> Value
Object Object
forall a. Monoid a => a
mempty)
      (Text -> [Pair] -> [Pair]
addType Text
"user" [ Key
"date" Key -> POSIXTime -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= POSIXTime
d, Key
"sender_user" Key -> User -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= User
su ])
    MessageOriginHiddenUser Text
_t POSIXTime
d Text
sun -> Value -> [Pair] -> Value
addJsonFields
      (Object -> Value
Object Object
forall a. Monoid a => a
mempty)
      (Text -> [Pair] -> [Pair]
addType Text
"hidden_user" [ Key
"date" Key -> POSIXTime -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= POSIXTime
d, Key
"sender_user_name" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
sun ])
    MessageOriginChat Text
_t POSIXTime
d Chat
sc Maybe Text
as -> Value -> [Pair] -> Value
addJsonFields
      (Object -> Value
Object Object
forall a. Monoid a => a
mempty)
      (Text -> [Pair] -> [Pair]
addType Text
"chat" [ Key
"date" Key -> POSIXTime -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= POSIXTime
d, Key
"sender_chat" Key -> Chat -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Chat
sc, Key
"author_signature" Key -> Maybe Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Maybe Text
as ])
    MessageOriginChannel Text
_t POSIXTime
d Chat
c MessageId
m Maybe Text
as -> Value -> [Pair] -> Value
addJsonFields
      (Object -> Value
Object Object
forall a. Monoid a => a
mempty)
      (Text -> [Pair] -> [Pair]
addType Text
"channel" [ Key
"date" Key -> POSIXTime -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= POSIXTime
d, Key
"chat" Key -> Chat -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Chat
c, Key
"message_id" Key -> MessageId -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= MessageId
m, Key
"author_signature" Key -> Maybe Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Maybe Text
as])

instance FromJSON MessageOrigin where
  parseJSON :: Value -> Parser MessageOrigin
parseJSON = String
-> (Object -> Parser MessageOrigin)
-> Value
-> Parser MessageOrigin
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"MessageOrigin" \Object
o ->
    (Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"type" :: Parser Text) Parser Text
-> (Text -> Parser MessageOrigin) -> Parser MessageOrigin
forall a b. Parser a -> (a -> Parser b) -> Parser b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Text
"user" -> Text -> POSIXTime -> User -> MessageOrigin
MessageOriginUser
      (Text -> POSIXTime -> User -> MessageOrigin)
-> Parser Text -> Parser (POSIXTime -> User -> MessageOrigin)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"type"
      Parser (POSIXTime -> User -> MessageOrigin)
-> Parser POSIXTime -> Parser (User -> MessageOrigin)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser POSIXTime
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"date"
      Parser (User -> MessageOrigin)
-> Parser User -> Parser MessageOrigin
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser User
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"sender_user"
    Text
"hidden_user" -> Text -> POSIXTime -> Text -> MessageOrigin
MessageOriginHiddenUser
      (Text -> POSIXTime -> Text -> MessageOrigin)
-> Parser Text -> Parser (POSIXTime -> Text -> MessageOrigin)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"type"
      Parser (POSIXTime -> Text -> MessageOrigin)
-> Parser POSIXTime -> Parser (Text -> MessageOrigin)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser POSIXTime
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"date"
      Parser (Text -> MessageOrigin)
-> Parser Text -> Parser MessageOrigin
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"sender_user_name"
    Text
"chat" -> Text -> POSIXTime -> Chat -> Maybe Text -> MessageOrigin
MessageOriginChat
      (Text -> POSIXTime -> Chat -> Maybe Text -> MessageOrigin)
-> Parser Text
-> Parser (POSIXTime -> Chat -> Maybe Text -> MessageOrigin)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"type"
      Parser (POSIXTime -> Chat -> Maybe Text -> MessageOrigin)
-> Parser POSIXTime -> Parser (Chat -> Maybe Text -> MessageOrigin)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser POSIXTime
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"date"
      Parser (Chat -> Maybe Text -> MessageOrigin)
-> Parser Chat -> Parser (Maybe Text -> MessageOrigin)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser Chat
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"sender_chat"
      Parser (Maybe Text -> MessageOrigin)
-> Parser (Maybe Text) -> Parser MessageOrigin
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"author_signature"
    Text
"channel" -> Text
-> POSIXTime -> Chat -> MessageId -> Maybe Text -> MessageOrigin
MessageOriginChannel
      (Text
 -> POSIXTime -> Chat -> MessageId -> Maybe Text -> MessageOrigin)
-> Parser Text
-> Parser
     (POSIXTime -> Chat -> MessageId -> Maybe Text -> MessageOrigin)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"type"
      Parser
  (POSIXTime -> Chat -> MessageId -> Maybe Text -> MessageOrigin)
-> Parser POSIXTime
-> Parser (Chat -> MessageId -> Maybe Text -> MessageOrigin)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser POSIXTime
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"date"
      Parser (Chat -> MessageId -> Maybe Text -> MessageOrigin)
-> Parser Chat -> Parser (MessageId -> Maybe Text -> MessageOrigin)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser Chat
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"chat"
      Parser (MessageId -> Maybe Text -> MessageOrigin)
-> Parser MessageId -> Parser (Maybe Text -> MessageOrigin)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser MessageId
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"message_id"
      Parser (Maybe Text -> MessageOrigin)
-> Parser (Maybe Text) -> Parser MessageOrigin
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"author_signature"
    Text
t -> String -> Parser MessageOrigin
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser MessageOrigin) -> String -> Parser MessageOrigin
forall a b. (a -> b) -> a -> b
$ Text -> String
Text.unpack (Text
"Unknown type: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
t)