{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE TemplateHaskell            #-}

module CoinbasePro.Authenticated.Limits
  ( Limits (..)
  ) where

import           Data.Aeson        (FromJSON, ToJSON, parseJSON, withText)
import           Data.Aeson.Casing (snakeCase)
import           Data.Aeson.TH     (defaultOptions, deriveJSON,
                                    fieldLabelModifier)
import           Data.Map.Strict   (Map)
import           Data.Text         (Text, unpack)

import           CoinbasePro.Types (ProductId)


newtype LimitCurrency = LimitCurrency Text
  deriving (LimitCurrency -> LimitCurrency -> Bool
(LimitCurrency -> LimitCurrency -> Bool)
-> (LimitCurrency -> LimitCurrency -> Bool) -> Eq LimitCurrency
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LimitCurrency -> LimitCurrency -> Bool
$c/= :: LimitCurrency -> LimitCurrency -> Bool
== :: LimitCurrency -> LimitCurrency -> Bool
$c== :: LimitCurrency -> LimitCurrency -> Bool
Eq, Int -> LimitCurrency -> ShowS
[LimitCurrency] -> ShowS
LimitCurrency -> String
(Int -> LimitCurrency -> ShowS)
-> (LimitCurrency -> String)
-> ([LimitCurrency] -> ShowS)
-> Show LimitCurrency
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LimitCurrency] -> ShowS
$cshowList :: [LimitCurrency] -> ShowS
show :: LimitCurrency -> String
$cshow :: LimitCurrency -> String
showsPrec :: Int -> LimitCurrency -> ShowS
$cshowsPrec :: Int -> LimitCurrency -> ShowS
Show, [LimitCurrency] -> Encoding
[LimitCurrency] -> Value
LimitCurrency -> Encoding
LimitCurrency -> Value
(LimitCurrency -> Value)
-> (LimitCurrency -> Encoding)
-> ([LimitCurrency] -> Value)
-> ([LimitCurrency] -> Encoding)
-> ToJSON LimitCurrency
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [LimitCurrency] -> Encoding
$ctoEncodingList :: [LimitCurrency] -> Encoding
toJSONList :: [LimitCurrency] -> Value
$ctoJSONList :: [LimitCurrency] -> Value
toEncoding :: LimitCurrency -> Encoding
$ctoEncoding :: LimitCurrency -> Encoding
toJSON :: LimitCurrency -> Value
$ctoJSON :: LimitCurrency -> Value
ToJSON, Value -> Parser [LimitCurrency]
Value -> Parser LimitCurrency
(Value -> Parser LimitCurrency)
-> (Value -> Parser [LimitCurrency]) -> FromJSON LimitCurrency
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [LimitCurrency]
$cparseJSONList :: Value -> Parser [LimitCurrency]
parseJSON :: Value -> Parser LimitCurrency
$cparseJSON :: Value -> Parser LimitCurrency
FromJSON)


newtype Max = Max Double
  deriving (Max -> Max -> Bool
(Max -> Max -> Bool) -> (Max -> Max -> Bool) -> Eq Max
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Max -> Max -> Bool
$c/= :: Max -> Max -> Bool
== :: Max -> Max -> Bool
$c== :: Max -> Max -> Bool
Eq, Int -> Max -> ShowS
[Max] -> ShowS
Max -> String
(Int -> Max -> ShowS)
-> (Max -> String) -> ([Max] -> ShowS) -> Show Max
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Max] -> ShowS
$cshowList :: [Max] -> ShowS
show :: Max -> String
$cshow :: Max -> String
showsPrec :: Int -> Max -> ShowS
$cshowsPrec :: Int -> Max -> ShowS
Show, [Max] -> Encoding
[Max] -> Value
Max -> Encoding
Max -> Value
(Max -> Value)
-> (Max -> Encoding)
-> ([Max] -> Value)
-> ([Max] -> Encoding)
-> ToJSON Max
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [Max] -> Encoding
$ctoEncodingList :: [Max] -> Encoding
toJSONList :: [Max] -> Value
$ctoJSONList :: [Max] -> Value
toEncoding :: Max -> Encoding
$ctoEncoding :: Max -> Encoding
toJSON :: Max -> Value
$ctoJSON :: Max -> Value
ToJSON, Value -> Parser [Max]
Value -> Parser Max
(Value -> Parser Max) -> (Value -> Parser [Max]) -> FromJSON Max
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [Max]
$cparseJSONList :: Value -> Parser [Max]
parseJSON :: Value -> Parser Max
$cparseJSON :: Value -> Parser Max
FromJSON)


newtype Remaining = Remaining Double
  deriving (Remaining -> Remaining -> Bool
(Remaining -> Remaining -> Bool)
-> (Remaining -> Remaining -> Bool) -> Eq Remaining
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Remaining -> Remaining -> Bool
$c/= :: Remaining -> Remaining -> Bool
== :: Remaining -> Remaining -> Bool
$c== :: Remaining -> Remaining -> Bool
Eq, Int -> Remaining -> ShowS
[Remaining] -> ShowS
Remaining -> String
(Int -> Remaining -> ShowS)
-> (Remaining -> String)
-> ([Remaining] -> ShowS)
-> Show Remaining
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Remaining] -> ShowS
$cshowList :: [Remaining] -> ShowS
show :: Remaining -> String
$cshow :: Remaining -> String
showsPrec :: Int -> Remaining -> ShowS
$cshowsPrec :: Int -> Remaining -> ShowS
Show, [Remaining] -> Encoding
[Remaining] -> Value
Remaining -> Encoding
Remaining -> Value
(Remaining -> Value)
-> (Remaining -> Encoding)
-> ([Remaining] -> Value)
-> ([Remaining] -> Encoding)
-> ToJSON Remaining
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [Remaining] -> Encoding
$ctoEncodingList :: [Remaining] -> Encoding
toJSONList :: [Remaining] -> Value
$ctoJSONList :: [Remaining] -> Value
toEncoding :: Remaining -> Encoding
$ctoEncoding :: Remaining -> Encoding
toJSON :: Remaining -> Value
$ctoJSON :: Remaining -> Value
ToJSON, Value -> Parser [Remaining]
Value -> Parser Remaining
(Value -> Parser Remaining)
-> (Value -> Parser [Remaining]) -> FromJSON Remaining
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [Remaining]
$cparseJSONList :: Value -> Parser [Remaining]
parseJSON :: Value -> Parser Remaining
$cparseJSON :: Value -> Parser Remaining
FromJSON)


newtype PeriodInDays = PeriodInDays Int
  deriving (PeriodInDays -> PeriodInDays -> Bool
(PeriodInDays -> PeriodInDays -> Bool)
-> (PeriodInDays -> PeriodInDays -> Bool) -> Eq PeriodInDays
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PeriodInDays -> PeriodInDays -> Bool
$c/= :: PeriodInDays -> PeriodInDays -> Bool
== :: PeriodInDays -> PeriodInDays -> Bool
$c== :: PeriodInDays -> PeriodInDays -> Bool
Eq, Int -> PeriodInDays -> ShowS
[PeriodInDays] -> ShowS
PeriodInDays -> String
(Int -> PeriodInDays -> ShowS)
-> (PeriodInDays -> String)
-> ([PeriodInDays] -> ShowS)
-> Show PeriodInDays
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PeriodInDays] -> ShowS
$cshowList :: [PeriodInDays] -> ShowS
show :: PeriodInDays -> String
$cshow :: PeriodInDays -> String
showsPrec :: Int -> PeriodInDays -> ShowS
$cshowsPrec :: Int -> PeriodInDays -> ShowS
Show, [PeriodInDays] -> Encoding
[PeriodInDays] -> Value
PeriodInDays -> Encoding
PeriodInDays -> Value
(PeriodInDays -> Value)
-> (PeriodInDays -> Encoding)
-> ([PeriodInDays] -> Value)
-> ([PeriodInDays] -> Encoding)
-> ToJSON PeriodInDays
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [PeriodInDays] -> Encoding
$ctoEncodingList :: [PeriodInDays] -> Encoding
toJSONList :: [PeriodInDays] -> Value
$ctoJSONList :: [PeriodInDays] -> Value
toEncoding :: PeriodInDays -> Encoding
$ctoEncoding :: PeriodInDays -> Encoding
toJSON :: PeriodInDays -> Value
$ctoJSON :: PeriodInDays -> Value
ToJSON)


instance FromJSON PeriodInDays where
  parseJSON :: Value -> Parser PeriodInDays
parseJSON = String
-> (Text -> Parser PeriodInDays) -> Value -> Parser PeriodInDays
forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"period_in_days" ((Text -> Parser PeriodInDays) -> Value -> Parser PeriodInDays)
-> (Text -> Parser PeriodInDays) -> Value -> Parser PeriodInDays
forall a b. (a -> b) -> a -> b
$ \Text
t ->
    PeriodInDays -> Parser PeriodInDays
forall (m :: * -> *) a. Monad m => a -> m a
return (PeriodInDays -> Parser PeriodInDays)
-> (String -> PeriodInDays) -> String -> Parser PeriodInDays
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> PeriodInDays
PeriodInDays (Int -> PeriodInDays) -> (String -> Int) -> String -> PeriodInDays
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Int
forall a. Read a => String -> a
read (String -> Parser PeriodInDays) -> String -> Parser PeriodInDays
forall a b. (a -> b) -> a -> b
$ Text -> String
unpack Text
t


data Limit = Limit
  { Limit -> Max
max          :: Max
  , Limit -> Remaining
remaining    :: Remaining
  , Limit -> Maybe PeriodInDays
periodInDays :: Maybe PeriodInDays
  } deriving (Limit -> Limit -> Bool
(Limit -> Limit -> Bool) -> (Limit -> Limit -> Bool) -> Eq Limit
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Limit -> Limit -> Bool
$c/= :: Limit -> Limit -> Bool
== :: Limit -> Limit -> Bool
$c== :: Limit -> Limit -> Bool
Eq, Int -> Limit -> ShowS
[Limit] -> ShowS
Limit -> String
(Int -> Limit -> ShowS)
-> (Limit -> String) -> ([Limit] -> ShowS) -> Show Limit
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Limit] -> ShowS
$cshowList :: [Limit] -> ShowS
show :: Limit -> String
$cshow :: Limit -> String
showsPrec :: Int -> Limit -> ShowS
$cshowsPrec :: Int -> Limit -> ShowS
Show)


deriveJSON defaultOptions { fieldLabelModifier = snakeCase } ''Limit


type LimitMap = Map ProductId Limit


data TransferLimits = TransferLimits
  { TransferLimits -> Maybe LimitMap
ach                  :: Maybe LimitMap
  , TransferLimits -> Maybe LimitMap
achNoBalance         :: Maybe LimitMap
  , TransferLimits -> Maybe LimitMap
creditDebitCard      :: Maybe LimitMap
  , TransferLimits -> Maybe LimitMap
achCurm              :: Maybe LimitMap
  , TransferLimits -> Maybe LimitMap
secure3dBuy          :: Maybe LimitMap
  , TransferLimits -> Maybe LimitMap
exchangeWithdraw     :: Maybe LimitMap
  , TransferLimits -> Maybe LimitMap
exchangeAch          :: Maybe LimitMap
  , TransferLimits -> Maybe LimitMap
paypalWithdrawal     :: Maybe LimitMap
  , TransferLimits -> Maybe LimitMap
instantAchWithdrawal :: Maybe LimitMap
  , TransferLimits -> Maybe LimitMap
instantBuy           :: Maybe LimitMap
  , TransferLimits -> Maybe LimitMap
buy                  :: Maybe LimitMap
  , TransferLimits -> Maybe LimitMap
sell                 :: Maybe LimitMap
  } deriving (TransferLimits -> TransferLimits -> Bool
(TransferLimits -> TransferLimits -> Bool)
-> (TransferLimits -> TransferLimits -> Bool) -> Eq TransferLimits
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TransferLimits -> TransferLimits -> Bool
$c/= :: TransferLimits -> TransferLimits -> Bool
== :: TransferLimits -> TransferLimits -> Bool
$c== :: TransferLimits -> TransferLimits -> Bool
Eq, Int -> TransferLimits -> ShowS
[TransferLimits] -> ShowS
TransferLimits -> String
(Int -> TransferLimits -> ShowS)
-> (TransferLimits -> String)
-> ([TransferLimits] -> ShowS)
-> Show TransferLimits
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TransferLimits] -> ShowS
$cshowList :: [TransferLimits] -> ShowS
show :: TransferLimits -> String
$cshow :: TransferLimits -> String
showsPrec :: Int -> TransferLimits -> ShowS
$cshowsPrec :: Int -> TransferLimits -> ShowS
Show)


deriveJSON defaultOptions { fieldLabelModifier = snakeCase } ''TransferLimits


data Limits = Limits
    { Limits -> LimitCurrency
limitCurrency  :: LimitCurrency
    , Limits -> TransferLimits
transferLimits :: TransferLimits
    } deriving (Limits -> Limits -> Bool
(Limits -> Limits -> Bool)
-> (Limits -> Limits -> Bool) -> Eq Limits
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Limits -> Limits -> Bool
$c/= :: Limits -> Limits -> Bool
== :: Limits -> Limits -> Bool
$c== :: Limits -> Limits -> Bool
Eq, Int -> Limits -> ShowS
[Limits] -> ShowS
Limits -> String
(Int -> Limits -> ShowS)
-> (Limits -> String) -> ([Limits] -> ShowS) -> Show Limits
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Limits] -> ShowS
$cshowList :: [Limits] -> ShowS
show :: Limits -> String
$cshow :: Limits -> String
showsPrec :: Int -> Limits -> ShowS
$cshowsPrec :: Int -> Limits -> ShowS
Show)


deriveJSON defaultOptions { fieldLabelModifier = snakeCase } ''Limits