{-# LANGUAGE StrictData #-}
module GitHub.Types.PayloadParser where

import           Data.Aeson          (FromJSON (..), ToJSON (..))
import           Data.Aeson.Types    (Parser, Value (..))
import qualified Data.List           as List
import           Data.Text           (Text)
import qualified Data.Text           as Text

import           GitHub.Types.Event
import           GitHub.Types.Events


data Payload
    = CheckRunEventPayload                 CheckRunEvent
    | CheckSuiteEventPayload               CheckSuiteEvent
    | CommitCommentEventPayload            CommitCommentEvent
    | CreateEventPayload                   CreateEvent
    | DeleteEventPayload                   DeleteEvent
    | DeploymentEventPayload               DeploymentEvent
    | DeploymentStatusEventPayload         DeploymentStatusEvent
    | ForkEventPayload                     ForkEvent
    | GollumEventPayload                   GollumEvent
    | IssueCommentEventPayload             IssueCommentEvent
    | IssuesEventPayload                   IssuesEvent
    | LabelEventPayload                    LabelEvent
    | MemberEventPayload                   MemberEvent
    | MembershipEventPayload               MembershipEvent
    | MilestoneEventPayload                MilestoneEvent
    | OrganizationEventPayload             OrganizationEvent
    | PageBuildEventPayload                PageBuildEvent
    | PingEventPayload                     PingEvent
    | PullRequestEventPayload              PullRequestEvent
    | PullRequestReviewCommentEventPayload PullRequestReviewCommentEvent
    | PullRequestReviewEventPayload        PullRequestReviewEvent
    | PushEventPayload                     PushEvent
    | ReleaseEventPayload                  ReleaseEvent
    | RepositoryEventPayload               RepositoryEvent
    | StarEventPayload                     StarEvent
    | StatusEventPayload                   StatusEvent
    | WatchEventPayload                    WatchEvent
    | WorkflowJobEventPayload              WorkflowJobEvent
    | WorkflowRunEventPayload              WorkflowRunEvent
    deriving (Payload -> Payload -> Bool
(Payload -> Payload -> Bool)
-> (Payload -> Payload -> Bool) -> Eq Payload
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Payload -> Payload -> Bool
$c/= :: Payload -> Payload -> Bool
== :: Payload -> Payload -> Bool
$c== :: Payload -> Payload -> Bool
Eq, Int -> Payload -> ShowS
[Payload] -> ShowS
Payload -> String
(Int -> Payload -> ShowS)
-> (Payload -> String) -> ([Payload] -> ShowS) -> Show Payload
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Payload] -> ShowS
$cshowList :: [Payload] -> ShowS
show :: Payload -> String
$cshow :: Payload -> String
showsPrec :: Int -> Payload -> ShowS
$cshowsPrec :: Int -> Payload -> ShowS
Show, ReadPrec [Payload]
ReadPrec Payload
Int -> ReadS Payload
ReadS [Payload]
(Int -> ReadS Payload)
-> ReadS [Payload]
-> ReadPrec Payload
-> ReadPrec [Payload]
-> Read Payload
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Payload]
$creadListPrec :: ReadPrec [Payload]
readPrec :: ReadPrec Payload
$creadPrec :: ReadPrec Payload
readList :: ReadS [Payload]
$creadList :: ReadS [Payload]
readsPrec :: Int -> ReadS Payload
$creadsPrec :: Int -> ReadS Payload
Read)


instance ToJSON Payload where
    toJSON :: Payload -> Value
toJSON (CheckRunEventPayload                 CheckRunEvent
x) = CheckRunEvent -> Value
forall a. ToJSON a => a -> Value
toJSON CheckRunEvent
x
    toJSON (CheckSuiteEventPayload               CheckSuiteEvent
x) = CheckSuiteEvent -> Value
forall a. ToJSON a => a -> Value
toJSON CheckSuiteEvent
x
    toJSON (CommitCommentEventPayload            CommitCommentEvent
x) = CommitCommentEvent -> Value
forall a. ToJSON a => a -> Value
toJSON CommitCommentEvent
x
    toJSON (CreateEventPayload                   CreateEvent
x) = CreateEvent -> Value
forall a. ToJSON a => a -> Value
toJSON CreateEvent
x
    toJSON (DeleteEventPayload                   DeleteEvent
x) = DeleteEvent -> Value
forall a. ToJSON a => a -> Value
toJSON DeleteEvent
x
    toJSON (DeploymentEventPayload               DeploymentEvent
x) = DeploymentEvent -> Value
forall a. ToJSON a => a -> Value
toJSON DeploymentEvent
x
    toJSON (DeploymentStatusEventPayload         DeploymentStatusEvent
x) = DeploymentStatusEvent -> Value
forall a. ToJSON a => a -> Value
toJSON DeploymentStatusEvent
x
    toJSON (ForkEventPayload                     ForkEvent
x) = ForkEvent -> Value
forall a. ToJSON a => a -> Value
toJSON ForkEvent
x
    toJSON (GollumEventPayload                   GollumEvent
x) = GollumEvent -> Value
forall a. ToJSON a => a -> Value
toJSON GollumEvent
x
    toJSON (IssueCommentEventPayload             IssueCommentEvent
x) = IssueCommentEvent -> Value
forall a. ToJSON a => a -> Value
toJSON IssueCommentEvent
x
    toJSON (IssuesEventPayload                   IssuesEvent
x) = IssuesEvent -> Value
forall a. ToJSON a => a -> Value
toJSON IssuesEvent
x
    toJSON (LabelEventPayload                    LabelEvent
x) = LabelEvent -> Value
forall a. ToJSON a => a -> Value
toJSON LabelEvent
x
    toJSON (MemberEventPayload                   MemberEvent
x) = MemberEvent -> Value
forall a. ToJSON a => a -> Value
toJSON MemberEvent
x
    toJSON (MembershipEventPayload               MembershipEvent
x) = MembershipEvent -> Value
forall a. ToJSON a => a -> Value
toJSON MembershipEvent
x
    toJSON (MilestoneEventPayload                MilestoneEvent
x) = MilestoneEvent -> Value
forall a. ToJSON a => a -> Value
toJSON MilestoneEvent
x
    toJSON (OrganizationEventPayload             OrganizationEvent
x) = OrganizationEvent -> Value
forall a. ToJSON a => a -> Value
toJSON OrganizationEvent
x
    toJSON (PageBuildEventPayload                PageBuildEvent
x) = PageBuildEvent -> Value
forall a. ToJSON a => a -> Value
toJSON PageBuildEvent
x
    toJSON (PingEventPayload                     PingEvent
x) = PingEvent -> Value
forall a. ToJSON a => a -> Value
toJSON PingEvent
x
    toJSON (PullRequestEventPayload              PullRequestEvent
x) = PullRequestEvent -> Value
forall a. ToJSON a => a -> Value
toJSON PullRequestEvent
x
    toJSON (PullRequestReviewCommentEventPayload PullRequestReviewCommentEvent
x) = PullRequestReviewCommentEvent -> Value
forall a. ToJSON a => a -> Value
toJSON PullRequestReviewCommentEvent
x
    toJSON (PullRequestReviewEventPayload        PullRequestReviewEvent
x) = PullRequestReviewEvent -> Value
forall a. ToJSON a => a -> Value
toJSON PullRequestReviewEvent
x
    toJSON (PushEventPayload                     PushEvent
x) = PushEvent -> Value
forall a. ToJSON a => a -> Value
toJSON PushEvent
x
    toJSON (ReleaseEventPayload                  ReleaseEvent
x) = ReleaseEvent -> Value
forall a. ToJSON a => a -> Value
toJSON ReleaseEvent
x
    toJSON (RepositoryEventPayload               RepositoryEvent
x) = RepositoryEvent -> Value
forall a. ToJSON a => a -> Value
toJSON RepositoryEvent
x
    toJSON (StatusEventPayload                   StatusEvent
x) = StatusEvent -> Value
forall a. ToJSON a => a -> Value
toJSON StatusEvent
x
    toJSON (StarEventPayload                     StarEvent
x) = StarEvent -> Value
forall a. ToJSON a => a -> Value
toJSON StarEvent
x
    toJSON (WatchEventPayload                    WatchEvent
x) = WatchEvent -> Value
forall a. ToJSON a => a -> Value
toJSON WatchEvent
x
    toJSON (WorkflowJobEventPayload              WorkflowJobEvent
x) = WorkflowJobEvent -> Value
forall a. ToJSON a => a -> Value
toJSON WorkflowJobEvent
x
    toJSON (WorkflowRunEventPayload              WorkflowRunEvent
x) = WorkflowRunEvent -> Value
forall a. ToJSON a => a -> Value
toJSON WorkflowRunEvent
x


data PayloadParser = PayloadParser
    { PayloadParser -> Text
payloadParserTypeName    :: Text
    , PayloadParser -> Text
payloadParserWebhookName :: Text
    , PayloadParser -> Value -> Parser Payload
payloadParser            :: Value -> Parser Payload
    }


payloadParsers :: [PayloadParser]
payloadParsers :: [PayloadParser]
payloadParsers =
    [ (CheckRunEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser CheckRunEvent -> Payload
CheckRunEventPayload
    , (CheckSuiteEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser CheckSuiteEvent -> Payload
CheckSuiteEventPayload
    , (CommitCommentEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser CommitCommentEvent -> Payload
CommitCommentEventPayload
    , (CreateEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser CreateEvent -> Payload
CreateEventPayload
    , (DeleteEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser DeleteEvent -> Payload
DeleteEventPayload
    , (DeploymentEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser DeploymentEvent -> Payload
DeploymentEventPayload
    , (DeploymentStatusEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser DeploymentStatusEvent -> Payload
DeploymentStatusEventPayload
    , (ForkEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser ForkEvent -> Payload
ForkEventPayload
    , (GollumEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser GollumEvent -> Payload
GollumEventPayload
    , (IssueCommentEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser IssueCommentEvent -> Payload
IssueCommentEventPayload
    , (IssuesEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser IssuesEvent -> Payload
IssuesEventPayload
    , (LabelEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser LabelEvent -> Payload
LabelEventPayload
    , (MemberEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser MemberEvent -> Payload
MemberEventPayload
    , (MembershipEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser MembershipEvent -> Payload
MembershipEventPayload
    , (MilestoneEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser MilestoneEvent -> Payload
MilestoneEventPayload
    , (OrganizationEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser OrganizationEvent -> Payload
OrganizationEventPayload
    , (PageBuildEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser PageBuildEvent -> Payload
PageBuildEventPayload
    , (PingEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser PingEvent -> Payload
PingEventPayload
    , (PullRequestEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser PullRequestEvent -> Payload
PullRequestEventPayload
    , (PullRequestReviewCommentEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser PullRequestReviewCommentEvent -> Payload
PullRequestReviewCommentEventPayload
    , (PullRequestReviewEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser PullRequestReviewEvent -> Payload
PullRequestReviewEventPayload
    , (PushEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser PushEvent -> Payload
PushEventPayload
    , (ReleaseEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser ReleaseEvent -> Payload
ReleaseEventPayload
    , (RepositoryEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser RepositoryEvent -> Payload
RepositoryEventPayload
    , (StatusEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser StatusEvent -> Payload
StatusEventPayload
    , (StarEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser StarEvent -> Payload
StarEventPayload
    , (WatchEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser WatchEvent -> Payload
WatchEventPayload
    , (WorkflowJobEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser WorkflowJobEvent -> Payload
WorkflowJobEventPayload
    , (WorkflowRunEvent -> Payload) -> PayloadParser
forall a. (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
eventParser WorkflowRunEvent -> Payload
WorkflowRunEventPayload
    ]
  where
    eventParser' :: FromJSON a => TypeName a -> EventName a -> (a -> Payload) -> PayloadParser
    eventParser' :: TypeName a -> EventName a -> (a -> Payload) -> PayloadParser
eventParser' (TypeName Text
ty) (EventName Text
ev) a -> Payload
tycon =
        Text -> Text -> (Value -> Parser Payload) -> PayloadParser
PayloadParser Text
ty Text
ev ((a -> Payload) -> Parser a -> Parser Payload
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> Payload
tycon (Parser a -> Parser Payload)
-> (Value -> Parser a) -> Value -> Parser Payload
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Parser a
forall a. FromJSON a => Value -> Parser a
parseJSON)

    eventParser :: (FromJSON a, Event a) => (a -> Payload) -> PayloadParser
    eventParser :: (a -> Payload) -> PayloadParser
eventParser = TypeName a -> EventName a -> (a -> Payload) -> PayloadParser
forall a.
FromJSON a =>
TypeName a -> EventName a -> (a -> Payload) -> PayloadParser
eventParser' TypeName a
forall a. Event a => TypeName a
typeName EventName a
forall a. Event a => EventName a
eventName



eventPayloadParser :: Text -> Value -> Parser Payload
eventPayloadParser :: Text -> Value -> Parser Payload
eventPayloadParser Text
eventType Value
x =
    case (PayloadParser -> Bool) -> [PayloadParser] -> Maybe PayloadParser
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
List.find ((Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
eventType) (Text -> Bool) -> (PayloadParser -> Text) -> PayloadParser -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PayloadParser -> Text
payloadParserTypeName) [PayloadParser]
payloadParsers of
        Maybe PayloadParser
Nothing -> String -> Parser Payload
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser Payload) -> String -> Parser Payload
forall a b. (a -> b) -> a -> b
$ String
"eventPayloadParser: unknown event type: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
Text.unpack Text
eventType
        Just PayloadParser
p  -> PayloadParser -> Value -> Parser Payload
payloadParser PayloadParser
p Value
x

-- | Since the event type is included through different means (X-GitHub-Event
-- header, or inline in the JSON object), it's not possible to make 'Event'
-- an instance of 'FromJSON'. But if you know the type, you can use this
-- parser.
webhookPayloadParser :: Text -> Value -> Parser Payload
webhookPayloadParser :: Text -> Value -> Parser Payload
webhookPayloadParser Text
eventType Value
x =
    case (PayloadParser -> Bool) -> [PayloadParser] -> Maybe PayloadParser
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
List.find ((Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
eventType) (Text -> Bool) -> (PayloadParser -> Text) -> PayloadParser -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PayloadParser -> Text
payloadParserWebhookName) [PayloadParser]
payloadParsers of
        Maybe PayloadParser
Nothing -> String -> Parser Payload
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser Payload) -> String -> Parser Payload
forall a b. (a -> b) -> a -> b
$ String
"webhookPayloadParser: unknown event type: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
Text.unpack Text
eventType
        Just PayloadParser
p  -> PayloadParser -> Value -> Parser Payload
payloadParser PayloadParser
p Value
x