content: {-# 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 = traverseSqs . 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 = lambdaMain . traverseSnsInSqs
  
  -- | Traverse S3 events embedded within SNS messages within an SQS event
  traverseS3InSnsInSqs :: (Applicative m) => (S3EventNotification -> m ()) -> SQSEvent (Embedded (SNSMessage (Embedded S3Event))) -> m ()
  traverseS3InSnsInSqs = traverseSnsInSqs . 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 = lambdaMain . traverseS3InSnsInSqs
  