{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Paddle.WebHook where


import           Protolude
import           Prelude ()
import           Servant.API
import           Web.FormUrlEncoded
import Paddle.WebHook.Signature (SignatureBody)
import Paddle.WebHook.SubscriptionCreated (SubscriptionCreated)
import Paddle.WebHook.SubscriptionCancelled (SubscriptionCancelled)
import Paddle.FieldModifier (modifier)

data PaddleWebHook passthrough 
  = SubscriptionCreatedWebHook (SubscriptionCreated passthrough)
  | SubscriptionCancelledWebHook (SubscriptionCancelled passthrough)
  | UnknownWebHook Text
  deriving ((forall x.
 PaddleWebHook passthrough -> Rep (PaddleWebHook passthrough) x)
-> (forall x.
    Rep (PaddleWebHook passthrough) x -> PaddleWebHook passthrough)
-> Generic (PaddleWebHook passthrough)
forall x.
Rep (PaddleWebHook passthrough) x -> PaddleWebHook passthrough
forall x.
PaddleWebHook passthrough -> Rep (PaddleWebHook passthrough) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall passthrough x.
Rep (PaddleWebHook passthrough) x -> PaddleWebHook passthrough
forall passthrough x.
PaddleWebHook passthrough -> Rep (PaddleWebHook passthrough) x
$cto :: forall passthrough x.
Rep (PaddleWebHook passthrough) x -> PaddleWebHook passthrough
$cfrom :: forall passthrough x.
PaddleWebHook passthrough -> Rep (PaddleWebHook passthrough) x
Generic, Int -> PaddleWebHook passthrough -> ShowS
[PaddleWebHook passthrough] -> ShowS
PaddleWebHook passthrough -> String
(Int -> PaddleWebHook passthrough -> ShowS)
-> (PaddleWebHook passthrough -> String)
-> ([PaddleWebHook passthrough] -> ShowS)
-> Show (PaddleWebHook passthrough)
forall passthrough.
Show passthrough =>
Int -> PaddleWebHook passthrough -> ShowS
forall passthrough.
Show passthrough =>
[PaddleWebHook passthrough] -> ShowS
forall passthrough.
Show passthrough =>
PaddleWebHook passthrough -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PaddleWebHook passthrough] -> ShowS
$cshowList :: forall passthrough.
Show passthrough =>
[PaddleWebHook passthrough] -> ShowS
show :: PaddleWebHook passthrough -> String
$cshow :: forall passthrough.
Show passthrough =>
PaddleWebHook passthrough -> String
showsPrec :: Int -> PaddleWebHook passthrough -> ShowS
$cshowsPrec :: forall passthrough.
Show passthrough =>
Int -> PaddleWebHook passthrough -> ShowS
Show)

-- TODO: validate request body using http://hackage.haskell.org/package/servant-0.16.2/docs/Servant-API-WithNamedContext.html
instance FromHttpApiData passthrough => FromForm (PaddleWebHook passthrough, SignatureBody) where
  fromForm :: Form -> Either Text (PaddleWebHook passthrough, SignatureBody)
fromForm Form
form = 
    Text -> Form -> Either Text Text
lookupUnique Text
"alert_name" Form
form Either Text Text
-> (Text -> Either Text (PaddleWebHook passthrough, SignatureBody))
-> Either Text (PaddleWebHook passthrough, SignatureBody)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (\Text
name -> (PaddleWebHook passthrough
 -> SignatureBody -> (PaddleWebHook passthrough, SignatureBody))
-> Either Text (PaddleWebHook passthrough)
-> Either Text SignatureBody
-> Either Text (PaddleWebHook passthrough, SignatureBody)
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (,) (Text -> Either Text (PaddleWebHook passthrough)
toWebHook Text
name) Either Text SignatureBody
signatureBody)
    where
      signatureBody :: Either Text SignatureBody
      signatureBody :: Either Text SignatureBody
signatureBody = Form -> Either Text SignatureBody
forall a. FromForm a => Form -> Either Text a
fromForm Form
form

      formOptions :: FormOptions
      formOptions :: FormOptions
formOptions =
        FormOptions
defaultFormOptions 
          { fieldLabelModifier :: ShowS
fieldLabelModifier = ShowS
modifier
          }

      toWebHook :: Text -> Either Text (PaddleWebHook passthrough)
      toWebHook :: Text -> Either Text (PaddleWebHook passthrough)
toWebHook Text
"subscription_created" = SubscriptionCreated passthrough -> PaddleWebHook passthrough
forall passthrough.
SubscriptionCreated passthrough -> PaddleWebHook passthrough
SubscriptionCreatedWebHook (SubscriptionCreated passthrough -> PaddleWebHook passthrough)
-> Either Text (SubscriptionCreated passthrough)
-> Either Text (PaddleWebHook passthrough)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FormOptions
-> Form -> Either Text (SubscriptionCreated passthrough)
forall a.
(Generic a, GFromForm a (Rep a)) =>
FormOptions -> Form -> Either Text a
genericFromForm FormOptions
formOptions Form
form
      toWebHook Text
"subscription_cancelled" = SubscriptionCancelled passthrough -> PaddleWebHook passthrough
forall passthrough.
SubscriptionCancelled passthrough -> PaddleWebHook passthrough
SubscriptionCancelledWebHook (SubscriptionCancelled passthrough -> PaddleWebHook passthrough)
-> Either Text (SubscriptionCancelled passthrough)
-> Either Text (PaddleWebHook passthrough)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FormOptions
-> Form -> Either Text (SubscriptionCancelled passthrough)
forall a.
(Generic a, GFromForm a (Rep a)) =>
FormOptions -> Form -> Either Text a
genericFromForm FormOptions
formOptions Form
form
      toWebHook Text
name = PaddleWebHook passthrough
-> Either Text (PaddleWebHook passthrough)
forall a b. b -> Either a b
Right (PaddleWebHook passthrough
 -> Either Text (PaddleWebHook passthrough))
-> PaddleWebHook passthrough
-> Either Text (PaddleWebHook passthrough)
forall a b. (a -> b) -> a -> b
$ Text -> PaddleWebHook passthrough
forall passthrough. Text -> PaddleWebHook passthrough
UnknownWebHook Text
name

type API passthrough
    = ReqBody '[FormUrlEncoded] (PaddleWebHook passthrough, SignatureBody)
    :> Post '[JSON] NoContent

api :: Proxy (API passthrough)
api :: Proxy (API passthrough)
api = Proxy (API passthrough)
forall k (t :: k). Proxy t
Proxy