module Amazon.SNS.Verify.Payload
  ( SNSPayload (..)
  , SNSType (..)
  , SNSNotification (..)
  , SNSSubscription (..)
  ) where

import Amazon.SNS.Verify.Prelude

import Data.Aeson
  ( FromJSON
  , defaultOptions
  , fieldLabelModifier
  , genericParseJSON
  , parseJSON
  , withObject
  , (.:)
  )
import GHC.Generics (Generic)

data SNSPayload = SNSPayload
  { SNSPayload -> Text
snsMessage :: Text
  , SNSPayload -> Text
snsMessageId :: Text
  , SNSPayload -> Text
snsTimestamp :: Text
  , SNSPayload -> Text
snsTopicArn :: Text
  , SNSPayload -> Text
snsType :: Text
  , SNSPayload -> Text
snsSignatureVersion :: Text
  , SNSPayload -> Text
snsSignature :: Text
  , SNSPayload -> Text
snsSigningCertURL :: Text
  , SNSPayload -> SNSType
snsTypePayload :: SNSType
  }

instance FromJSON SNSPayload where
  parseJSON :: Value -> Parser SNSPayload
parseJSON Value
v = Value -> Parser SNSPayload
parse Value
v
   where
    parse :: Value -> Parser SNSPayload
parse = forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"SNSPayload" forall a b. (a -> b) -> a -> b
$ \Object
o -> do
      Text
payloadType <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Type"
      Text
-> Text
-> Text
-> Text
-> Text
-> Text
-> Text
-> Text
-> SNSType
-> SNSPayload
SNSPayload
        forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o
        forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Message"
        forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o
        forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"MessageId"
        forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o
        forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Timestamp"
        forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o
        forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"TopicArn"
        forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
payloadType
        forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o
        forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"SignatureVersion"
        forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o
        forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Signature"
        forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o
        forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"SigningCertURL"
        forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> Parser SNSType
parseType Text
payloadType
    parseType :: Text -> Parser SNSType
parseType = \case
      Text
"SubscriptionConfirmation" -> SNSSubscription -> SNSType
SubscriptionConfirmation forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromJSON a => Value -> Parser a
parseJSON Value
v
      Text
"UnsubscribeConfirmation" -> SNSSubscription -> SNSType
UnsubscribeConfirmation forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromJSON a => Value -> Parser a
parseJSON Value
v
      Text
"Notification" -> SNSNotification -> SNSType
Notification forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromJSON a => Value -> Parser a
parseJSON Value
v
      Text
msg -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"Unknown message type " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show Text
msg

data SNSType
  = Notification SNSNotification
  | SubscriptionConfirmation SNSSubscription
  | UnsubscribeConfirmation SNSSubscription

newtype SNSNotification = SNSNotification
  { SNSNotification -> Maybe Text
snsSubject :: Maybe Text
  }
  deriving stock (Int -> SNSNotification -> ShowS
[SNSNotification] -> ShowS
SNSNotification -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SNSNotification] -> ShowS
$cshowList :: [SNSNotification] -> ShowS
show :: SNSNotification -> String
$cshow :: SNSNotification -> String
showsPrec :: Int -> SNSNotification -> ShowS
$cshowsPrec :: Int -> SNSNotification -> ShowS
Show, SNSNotification -> SNSNotification -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SNSNotification -> SNSNotification -> Bool
$c/= :: SNSNotification -> SNSNotification -> Bool
== :: SNSNotification -> SNSNotification -> Bool
$c== :: SNSNotification -> SNSNotification -> Bool
Eq, forall x. Rep SNSNotification x -> SNSNotification
forall x. SNSNotification -> Rep SNSNotification x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SNSNotification x -> SNSNotification
$cfrom :: forall x. SNSNotification -> Rep SNSNotification x
Generic)

instance FromJSON SNSNotification where
  parseJSON :: Value -> Parser SNSNotification
parseJSON = forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON forall a b. (a -> b) -> a -> b
$ Options
defaultOptions {fieldLabelModifier :: ShowS
fieldLabelModifier = forall a. Int -> [a] -> [a]
drop Int
3}

data SNSSubscription = SNSSubscription
  { SNSSubscription -> Text
snsToken :: Text
  , SNSSubscription -> Text
snsSubscribeURL :: Text
  }
  deriving stock (Int -> SNSSubscription -> ShowS
[SNSSubscription] -> ShowS
SNSSubscription -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SNSSubscription] -> ShowS
$cshowList :: [SNSSubscription] -> ShowS
show :: SNSSubscription -> String
$cshow :: SNSSubscription -> String
showsPrec :: Int -> SNSSubscription -> ShowS
$cshowsPrec :: Int -> SNSSubscription -> ShowS
Show, SNSSubscription -> SNSSubscription -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SNSSubscription -> SNSSubscription -> Bool
$c/= :: SNSSubscription -> SNSSubscription -> Bool
== :: SNSSubscription -> SNSSubscription -> Bool
$c== :: SNSSubscription -> SNSSubscription -> Bool
Eq, forall x. Rep SNSSubscription x -> SNSSubscription
forall x. SNSSubscription -> Rep SNSSubscription x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SNSSubscription x -> SNSSubscription
$cfrom :: forall x. SNSSubscription -> Rep SNSSubscription x
Generic)

instance FromJSON SNSSubscription where
  parseJSON :: Value -> Parser SNSSubscription
parseJSON = forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON forall a b. (a -> b) -> a -> b
$ Options
defaultOptions {fieldLabelModifier :: ShowS
fieldLabelModifier = forall a. Int -> [a] -> [a]
drop Int
3}