{-# LANGUAGE DataKinds     #-}
{-# LANGUAGE TypeOperators #-}

module CoinbasePro.Unauthenticated.API
    ( products
    , singleProduct
    , aggregateOrderBook
    , fullOrderBook
    , trades
    , candles
    , stats
    , currencies
    , time
    ) where

import           Data.Proxy                                (Proxy (..))
import           Data.Time.Clock                           (UTCTime)
import           Servant.API                               ((:<|>) (..), (:>),
                                                            Capture, QueryParam,
                                                            QueryParam',
                                                            Required)
import           Servant.Client                            (client)

import           CoinbasePro.MarketData.AggregateOrderBook (AggregateOrderBook)
import           CoinbasePro.MarketData.FullOrderBook      (FullOrderBook)
import           CoinbasePro.MarketData.Types              (AggregateBookLevel (..),
                                                            CBTime,
                                                            FullBookLevel (..),
                                                            Product, Trade)
import           CoinbasePro.Request                       (CBGet, CBRequest)
import           CoinbasePro.Types                         (Candle,
                                                            CandleGranularity,
                                                            Currency, ProductId,
                                                            TwentyFourHourStats)


type Products = "products" :> CBGet [Product]

type ProductSingle = "products"
                   :> Capture "product" ProductId
                   :> CBGet Product

type ProductAggregateOrderBook = "products"
                               :> Capture "product" ProductId
                               :> "book"
                               :> QueryParam "level" AggregateBookLevel
                               :> CBGet AggregateOrderBook

type ProductFullOrderBook = "products"
                          :> Capture "product" ProductId
                          :> "book"
                          :> QueryParam "level" FullBookLevel
                          :> CBGet FullOrderBook

type Trades = "products"
            :> Capture "product" ProductId
            :> "trades"
            :> CBGet [Trade]

type Candles = "products"
             :> Capture "product" ProductId
             :> "candles"
             :> QueryParam "start" UTCTime
             :> QueryParam "end" UTCTime
             :> QueryParam' '[Required] "granularity" CandleGranularity
             :> CBGet [Candle]

type Stats = "products"
            :> Capture "product" ProductId
            :> "stats"
            :> CBGet TwentyFourHourStats

type Currencies = "currencies"
                :> CBGet [Currency]

type Time = "time" :> CBGet CBTime

type API =    Products
         :<|> ProductSingle
         :<|> ProductAggregateOrderBook
         :<|> ProductFullOrderBook
         :<|> Trades
         :<|> Candles
         :<|> Stats
         :<|> Currencies
         :<|> Time


api :: Proxy API
api :: Proxy API
api = forall {k} (t :: k). Proxy t
Proxy


products :: CBRequest [Product]
singleProduct :: ProductId -> CBRequest Product
aggregateOrderBook :: ProductId -> Maybe AggregateBookLevel -> CBRequest AggregateOrderBook
fullOrderBook :: ProductId -> Maybe FullBookLevel -> CBRequest FullOrderBook
trades :: ProductId -> CBRequest [Trade]
candles :: ProductId -> Maybe UTCTime -> Maybe UTCTime -> CandleGranularity -> CBRequest [Candle]
stats :: ProductId -> CBRequest TwentyFourHourStats
currencies :: CBRequest [Currency]
time :: CBRequest CBTime
CBRequest [Product]
products :<|> ProductId -> CBRequest Product
singleProduct :<|> ProductId
-> Maybe AggregateBookLevel -> CBRequest AggregateOrderBook
aggregateOrderBook :<|> ProductId -> Maybe FullBookLevel -> CBRequest FullOrderBook
fullOrderBook :<|> ProductId -> CBRequest [Trade]
trades :<|> ProductId
-> Maybe UTCTime
-> Maybe UTCTime
-> CandleGranularity
-> CBRequest [Candle]
candles :<|> ProductId -> CBRequest TwentyFourHourStats
stats :<|> CBRequest [Currency]
currencies :<|> CBRequest CBTime
time = forall api.
HasClient ClientM api =>
Proxy api -> Client ClientM api
client Proxy API
api