module MixPanel.Types.Core
  ( AuthToken(..)
  , Toggle(..)
  , DidSucceed(..)
  ) where

import           Data.Aeson                     ( ToJSON
                                                , FromJSON
                                                , parseJSON
                                                , toJSON
                                                , withObject
                                                , (.:)
                                                )
import           Data.Text                      ( Text )
import           GHC.Generics                   ( Generic )
import           Servant.API

newtype AuthToken = AuthToken Text
  deriving ((forall x. AuthToken -> Rep AuthToken x)
-> (forall x. Rep AuthToken x -> AuthToken) -> Generic AuthToken
forall x. Rep AuthToken x -> AuthToken
forall x. AuthToken -> Rep AuthToken x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep AuthToken x -> AuthToken
$cfrom :: forall x. AuthToken -> Rep AuthToken x
Generic, [AuthToken] -> Encoding
[AuthToken] -> Value
AuthToken -> Encoding
AuthToken -> Value
(AuthToken -> Value)
-> (AuthToken -> Encoding)
-> ([AuthToken] -> Value)
-> ([AuthToken] -> Encoding)
-> ToJSON AuthToken
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [AuthToken] -> Encoding
$ctoEncodingList :: [AuthToken] -> Encoding
toJSONList :: [AuthToken] -> Value
$ctoJSONList :: [AuthToken] -> Value
toEncoding :: AuthToken -> Encoding
$ctoEncoding :: AuthToken -> Encoding
toJSON :: AuthToken -> Value
$ctoJSON :: AuthToken -> Value
ToJSON)

-- | MixPanel API uses boolean logic with 1 or 0,
-- | so we have a special type for it
data Toggle = On | Off
  deriving (Int -> Toggle -> ShowS
[Toggle] -> ShowS
Toggle -> String
(Int -> Toggle -> ShowS)
-> (Toggle -> String) -> ([Toggle] -> ShowS) -> Show Toggle
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Toggle] -> ShowS
$cshowList :: [Toggle] -> ShowS
show :: Toggle -> String
$cshow :: Toggle -> String
showsPrec :: Int -> Toggle -> ShowS
$cshowsPrec :: Int -> Toggle -> ShowS
Show)

instance ToJSON Toggle where
  toJSON :: Toggle -> Value
toJSON Toggle
On = Value
"1"
  toJSON Toggle
Off = Value
"0"

instance ToHttpApiData Toggle where
  toUrlPiece :: Toggle -> Text
toUrlPiece Toggle
On = Text
"1"
  toUrlPiece Toggle
Off = Text
"0"


data DidSucceed = Success | Fail Text
  deriving (Int -> DidSucceed -> ShowS
[DidSucceed] -> ShowS
DidSucceed -> String
(Int -> DidSucceed -> ShowS)
-> (DidSucceed -> String)
-> ([DidSucceed] -> ShowS)
-> Show DidSucceed
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DidSucceed] -> ShowS
$cshowList :: [DidSucceed] -> ShowS
show :: DidSucceed -> String
$cshow :: DidSucceed -> String
showsPrec :: Int -> DidSucceed -> ShowS
$cshowsPrec :: Int -> DidSucceed -> ShowS
Show)

instance FromJSON DidSucceed where
  parseJSON :: Value -> Parser DidSucceed
parseJSON = String
-> (Object -> Parser DidSucceed) -> Value -> Parser DidSucceed
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"success or failure" ((Object -> Parser DidSucceed) -> Value -> Parser DidSucceed)
-> (Object -> Parser DidSucceed) -> Value -> Parser DidSucceed
forall a b. (a -> b) -> a -> b
$ \Object
o -> do
    Int
status <- Object
o Object -> Text -> Parser Int
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"status"
    case (Int
status :: Int) of
      Int
1 -> DidSucceed -> Parser DidSucceed
forall (m :: * -> *) a. Monad m => a -> m a
return DidSucceed
Success
      Int
0 -> Text -> DidSucceed
Fail (Text -> DidSucceed) -> Parser Text -> Parser DidSucceed
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
"error"
      Int
_ -> String -> Parser DidSucceed
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"unknown status: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
status)