{-# LANGUAGE DeriveGeneric   #-}
{-# LANGUAGE TemplateHaskell #-}

module AWSLambda.Events
  ( module AWSLambda.Events.APIGateway
  , module AWSLambda.Events.KinesisEvent
  , module AWSLambda.Events.MessageAttribute
  , module AWSLambda.Events.Records
  , module AWSLambda.Events.S3Event
  , module AWSLambda.Events.SNSEvent
  , module AWSLambda.Events.SQSEvent
  , traverseSnsInSqs
  , snsInSqsMain
  , traverseS3InSnsInSqs
  , s3InSnsInSqsMain
  ) where

import           Control.Exception.Safe            (MonadCatch)
import           Control.Monad.IO.Class
import           Data.Aeson                        (FromJSON (..))

import           AWSLambda.Events.APIGateway
import           AWSLambda.Events.KinesisEvent
import           AWSLambda.Events.MessageAttribute
import           AWSLambda.Events.Records
import           AWSLambda.Events.S3Event
import           AWSLambda.Events.SNSEvent
import           AWSLambda.Events.SQSEvent
import           AWSLambda.Handler                 (lambdaMain)
import           Data.Aeson.Embedded               (Embedded)

-- | Traverse all the SNS messages embedded in an SQS event
traverseSnsInSqs :: (FromJSON a, Applicative m) => (a -> m ()) -> SQSEvent (Embedded (SNSMessage (Embedded a))) -> m ()
traverseSnsInSqs :: (a -> m ())
-> SQSEvent (Embedded (SNSMessage (Embedded a))) -> m ()
traverseSnsInSqs = (SNSMessage (Embedded a) -> m ())
-> SQSEvent (Embedded (SNSMessage (Embedded a))) -> m ()
forall a (m :: * -> *).
(FromJSON a, Applicative m) =>
(a -> m ()) -> SQSEvent (Embedded a) -> m ()
traverseSqs ((SNSMessage (Embedded a) -> m ())
 -> SQSEvent (Embedded (SNSMessage (Embedded a))) -> m ())
-> ((a -> m ()) -> SNSMessage (Embedded a) -> m ())
-> (a -> m ())
-> SQSEvent (Embedded (SNSMessage (Embedded a)))
-> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> m ()) -> SNSMessage (Embedded a) -> m ()
forall a (m :: * -> *).
(FromJSON a, Applicative m) =>
(a -> m ()) -> SNSMessage (Embedded a) -> m ()
traverseSnsMessage

-- | A specialised version of the 'lambdaMain' entry-point
-- for handling individual SNS messages embedded in an SQS event
snsInSqsMain :: (FromJSON a, MonadCatch m, MonadIO m) => (a -> m ()) -> m ()
snsInSqsMain :: (a -> m ()) -> m ()
snsInSqsMain = (SQSEvent (Embedded (SNSMessage (Embedded a))) -> m ()) -> m ()
forall event res (m :: * -> *).
(FromJSON event, ToJSON res, MonadCatch m, MonadIO m) =>
(event -> m res) -> m ()
lambdaMain ((SQSEvent (Embedded (SNSMessage (Embedded a))) -> m ()) -> m ())
-> ((a -> m ())
    -> SQSEvent (Embedded (SNSMessage (Embedded a))) -> m ())
-> (a -> m ())
-> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> m ())
-> SQSEvent (Embedded (SNSMessage (Embedded a))) -> m ()
forall a (m :: * -> *).
(FromJSON a, Applicative m) =>
(a -> m ())
-> SQSEvent (Embedded (SNSMessage (Embedded a))) -> m ()
traverseSnsInSqs

-- | Traverse S3 events embedded within SNS messages within an SQS event
traverseS3InSnsInSqs :: (Applicative m) => (S3EventNotification -> m ()) -> SQSEvent (Embedded (SNSMessage (Embedded S3Event))) -> m ()
traverseS3InSnsInSqs :: (S3EventNotification -> m ())
-> SQSEvent (Embedded (SNSMessage (Embedded S3Event))) -> m ()
traverseS3InSnsInSqs = (S3Event -> m ())
-> SQSEvent (Embedded (SNSMessage (Embedded S3Event))) -> m ()
forall a (m :: * -> *).
(FromJSON a, Applicative m) =>
(a -> m ())
-> SQSEvent (Embedded (SNSMessage (Embedded a))) -> m ()
traverseSnsInSqs ((S3Event -> m ())
 -> SQSEvent (Embedded (SNSMessage (Embedded S3Event))) -> m ())
-> ((S3EventNotification -> m ()) -> S3Event -> m ())
-> (S3EventNotification -> m ())
-> SQSEvent (Embedded (SNSMessage (Embedded S3Event)))
-> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (S3EventNotification -> m ()) -> S3Event -> m ()
forall (m :: * -> *) a.
Applicative m =>
(a -> m ()) -> RecordsEvent a -> m ()
traverseRecords

-- | A specialised version of the 'lambdaMain' entry-point
-- for handling individual S3 event notifications embedded in
-- SNS messages embedded in an SQS event
s3InSnsInSqsMain :: (MonadCatch m, MonadIO m) => (S3EventNotification -> m ()) -> m ()
s3InSnsInSqsMain :: (S3EventNotification -> m ()) -> m ()
s3InSnsInSqsMain = (SQSEvent (Embedded (SNSMessage (Embedded S3Event))) -> m ())
-> m ()
forall event res (m :: * -> *).
(FromJSON event, ToJSON res, MonadCatch m, MonadIO m) =>
(event -> m res) -> m ()
lambdaMain ((SQSEvent (Embedded (SNSMessage (Embedded S3Event))) -> m ())
 -> m ())
-> ((S3EventNotification -> m ())
    -> SQSEvent (Embedded (SNSMessage (Embedded S3Event))) -> m ())
-> (S3EventNotification -> m ())
-> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (S3EventNotification -> m ())
-> SQSEvent (Embedded (SNSMessage (Embedded S3Event))) -> m ()
forall (m :: * -> *).
Applicative m =>
(S3EventNotification -> m ())
-> SQSEvent (Embedded (SNSMessage (Embedded S3Event))) -> m ()
traverseS3InSnsInSqs