{-# LANGUAGE OverloadedStrings #-}

module CoinbasePro.MarketData.AggregateOrderBook
    ( AggregateOrderBook(..)
    , AggregateLevel(..)
    ) where

import           Data.Aeson  (FromJSON (..), withArray, withObject, (.:))
import qualified Data.Vector as V
import           Data.Word   (Word64)


data AggregateOrderBook = AggregateOrderBook
    { AggregateOrderBook -> Int
sequence :: Int
    , AggregateOrderBook -> [AggregateLevel]
bids     :: [AggregateLevel]
    , AggregateOrderBook -> [AggregateLevel]
asks     :: [AggregateLevel]
    } deriving (AggregateOrderBook -> AggregateOrderBook -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AggregateOrderBook -> AggregateOrderBook -> Bool
$c/= :: AggregateOrderBook -> AggregateOrderBook -> Bool
== :: AggregateOrderBook -> AggregateOrderBook -> Bool
$c== :: AggregateOrderBook -> AggregateOrderBook -> Bool
Eq, Eq AggregateOrderBook
AggregateOrderBook -> AggregateOrderBook -> Bool
AggregateOrderBook -> AggregateOrderBook -> Ordering
AggregateOrderBook -> AggregateOrderBook -> AggregateOrderBook
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: AggregateOrderBook -> AggregateOrderBook -> AggregateOrderBook
$cmin :: AggregateOrderBook -> AggregateOrderBook -> AggregateOrderBook
max :: AggregateOrderBook -> AggregateOrderBook -> AggregateOrderBook
$cmax :: AggregateOrderBook -> AggregateOrderBook -> AggregateOrderBook
>= :: AggregateOrderBook -> AggregateOrderBook -> Bool
$c>= :: AggregateOrderBook -> AggregateOrderBook -> Bool
> :: AggregateOrderBook -> AggregateOrderBook -> Bool
$c> :: AggregateOrderBook -> AggregateOrderBook -> Bool
<= :: AggregateOrderBook -> AggregateOrderBook -> Bool
$c<= :: AggregateOrderBook -> AggregateOrderBook -> Bool
< :: AggregateOrderBook -> AggregateOrderBook -> Bool
$c< :: AggregateOrderBook -> AggregateOrderBook -> Bool
compare :: AggregateOrderBook -> AggregateOrderBook -> Ordering
$ccompare :: AggregateOrderBook -> AggregateOrderBook -> Ordering
Ord, Int -> AggregateOrderBook -> ShowS
[AggregateOrderBook] -> ShowS
AggregateOrderBook -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AggregateOrderBook] -> ShowS
$cshowList :: [AggregateOrderBook] -> ShowS
show :: AggregateOrderBook -> String
$cshow :: AggregateOrderBook -> String
showsPrec :: Int -> AggregateOrderBook -> ShowS
$cshowsPrec :: Int -> AggregateOrderBook -> ShowS
Show)


instance FromJSON AggregateOrderBook where
    parseJSON :: Value -> Parser AggregateOrderBook
parseJSON = forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"aggregate orderbook" forall a b. (a -> b) -> a -> b
$ \Object
o ->
        Int -> [AggregateLevel] -> [AggregateLevel] -> AggregateOrderBook
AggregateOrderBook forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
            Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"sequence" forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
            Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"bids" forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
            Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"asks"


data AggregateLevel = AggregateLevel
    { AggregateLevel -> Double
price     :: Double
    , AggregateLevel -> Double
size      :: Double
    , AggregateLevel -> Word64
numOrders :: Word64
    } deriving (AggregateLevel -> AggregateLevel -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AggregateLevel -> AggregateLevel -> Bool
$c/= :: AggregateLevel -> AggregateLevel -> Bool
== :: AggregateLevel -> AggregateLevel -> Bool
$c== :: AggregateLevel -> AggregateLevel -> Bool
Eq, Eq AggregateLevel
AggregateLevel -> AggregateLevel -> Bool
AggregateLevel -> AggregateLevel -> Ordering
AggregateLevel -> AggregateLevel -> AggregateLevel
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: AggregateLevel -> AggregateLevel -> AggregateLevel
$cmin :: AggregateLevel -> AggregateLevel -> AggregateLevel
max :: AggregateLevel -> AggregateLevel -> AggregateLevel
$cmax :: AggregateLevel -> AggregateLevel -> AggregateLevel
>= :: AggregateLevel -> AggregateLevel -> Bool
$c>= :: AggregateLevel -> AggregateLevel -> Bool
> :: AggregateLevel -> AggregateLevel -> Bool
$c> :: AggregateLevel -> AggregateLevel -> Bool
<= :: AggregateLevel -> AggregateLevel -> Bool
$c<= :: AggregateLevel -> AggregateLevel -> Bool
< :: AggregateLevel -> AggregateLevel -> Bool
$c< :: AggregateLevel -> AggregateLevel -> Bool
compare :: AggregateLevel -> AggregateLevel -> Ordering
$ccompare :: AggregateLevel -> AggregateLevel -> Ordering
Ord, Int -> AggregateLevel -> ShowS
[AggregateLevel] -> ShowS
AggregateLevel -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AggregateLevel] -> ShowS
$cshowList :: [AggregateLevel] -> ShowS
show :: AggregateLevel -> String
$cshow :: AggregateLevel -> String
showsPrec :: Int -> AggregateLevel -> ShowS
$cshowsPrec :: Int -> AggregateLevel -> ShowS
Show)


instance FromJSON AggregateLevel where
    parseJSON :: Value -> Parser AggregateLevel
parseJSON = forall a. String -> (Array -> Parser a) -> Value -> Parser a
withArray String
"level" forall a b. (a -> b) -> a -> b
$ \Array
a -> do
        let l :: [Value]
l = forall a. Vector a -> [a]
V.toList Array
a
        String
p   <- forall a. FromJSON a => Value -> Parser a
parseJSON forall a b. (a -> b) -> a -> b
$ forall a. [a] -> a
head [Value]
l
        String
sz  <- forall a. FromJSON a => Value -> Parser a
parseJSON forall a b. (a -> b) -> a -> b
$ [Value]
l forall a. [a] -> Int -> a
!! Int
1
        Word64
nos <- forall a. FromJSON a => Value -> Parser a
parseJSON forall a b. (a -> b) -> a -> b
$ [Value]
l forall a. [a] -> Int -> a
!! Int
2
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Double -> Double -> Word64 -> AggregateLevel
AggregateLevel (forall a. Read a => String -> a
read String
p) (forall a. Read a => String -> a
read String
sz) Word64
nos