{-# LANGUAGE OverloadedStrings #-}

module Control.Distributed.Fork.AWS.Lambda.Internal.Types where

import Control.Applicative
import Control.Monad
import Data.Aeson
import Data.Text (Text)
import qualified Data.Text as T

newtype BucketName = BucketName Text
  deriving (BucketName -> BucketName -> Bool
(BucketName -> BucketName -> Bool)
-> (BucketName -> BucketName -> Bool) -> Eq BucketName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BucketName -> BucketName -> Bool
$c/= :: BucketName -> BucketName -> Bool
== :: BucketName -> BucketName -> Bool
$c== :: BucketName -> BucketName -> Bool
Eq, Int -> BucketName -> ShowS
[BucketName] -> ShowS
BucketName -> String
(Int -> BucketName -> ShowS)
-> (BucketName -> String)
-> ([BucketName] -> ShowS)
-> Show BucketName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BucketName] -> ShowS
$cshowList :: [BucketName] -> ShowS
show :: BucketName -> String
$cshow :: BucketName -> String
showsPrec :: Int -> BucketName -> ShowS
$cshowsPrec :: Int -> BucketName -> ShowS
Show)

data S3Loc = S3Loc BucketName Text
  deriving (S3Loc -> S3Loc -> Bool
(S3Loc -> S3Loc -> Bool) -> (S3Loc -> S3Loc -> Bool) -> Eq S3Loc
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: S3Loc -> S3Loc -> Bool
$c/= :: S3Loc -> S3Loc -> Bool
== :: S3Loc -> S3Loc -> Bool
$c== :: S3Loc -> S3Loc -> Bool
Eq)

instance Show S3Loc where
  show :: S3Loc -> String
show (S3Loc (BucketName Text
bucket) Text
path) = Text -> String
T.unpack (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ Text
"s3://" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
bucket Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"/" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
path

newtype StackName = StackName {StackName -> Text
unStackName :: Text}
  deriving (StackName -> StackName -> Bool
(StackName -> StackName -> Bool)
-> (StackName -> StackName -> Bool) -> Eq StackName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: StackName -> StackName -> Bool
$c/= :: StackName -> StackName -> Bool
== :: StackName -> StackName -> Bool
$c== :: StackName -> StackName -> Bool
Eq, Int -> StackName -> ShowS
[StackName] -> ShowS
StackName -> String
(Int -> StackName -> ShowS)
-> (StackName -> String)
-> ([StackName] -> ShowS)
-> Show StackName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [StackName] -> ShowS
$cshowList :: [StackName] -> ShowS
show :: StackName -> String
$cshow :: StackName -> String
showsPrec :: Int -> StackName -> ShowS
$cshowsPrec :: Int -> StackName -> ShowS
Show)

data StackOptions
  = StackOptions
      { StackOptions -> StackName
soName :: StackName,
        StackOptions -> Int
soLambdaMemory :: Int,
        StackOptions -> S3Loc
soLambdaCode :: S3Loc,
        StackOptions -> Bool
soKeep :: Bool
      }

data Response
  = Response Int ResponsePayload

data ResponsePayload
  = ResponsePayloadInline Text
  | ResponsePayloadS3 Text

instance FromJSON Response where
  parseJSON :: Value -> Parser Response
parseJSON (Object Object
obj) =
    Int -> ResponsePayload -> Response
Response
      (Int -> ResponsePayload -> Response)
-> Parser Int -> Parser (ResponsePayload -> Response)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
obj Object -> Text -> Parser Int
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"id"
      Parser (ResponsePayload -> Response)
-> Parser ResponsePayload -> Parser Response
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Object -> Parser ResponsePayload
parseInline Object
obj Parser ResponsePayload
-> Parser ResponsePayload -> Parser ResponsePayload
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Object -> Parser ResponsePayload
parseS3 Object
obj)
    where
      parseInline :: Object -> Parser ResponsePayload
parseInline Object
o = do
        Text
ty <- Object
o Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"type"
        Bool -> Parser ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Parser ()) -> Bool -> Parser ()
forall a b. (a -> b) -> a -> b
$ (Text
ty :: Text) Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"response-inline"
        Text -> ResponsePayload
ResponsePayloadInline (Text -> ResponsePayload) -> Parser Text -> Parser ResponsePayload
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"payload"
      parseS3 :: Object -> Parser ResponsePayload
parseS3 Object
o = do
        Text
ty <- Object
o Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"type"
        Bool -> Parser ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Parser ()) -> Bool -> Parser ()
forall a b. (a -> b) -> a -> b
$ (Text
ty :: Text) Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"response-s3"
        Text -> ResponsePayload
ResponsePayloadS3 (Text -> ResponsePayload) -> Parser Text -> Parser ResponsePayload
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"path"
  parseJSON Value
_ = String -> Parser Response
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"unexpected response"