{-# LANGUAGE OverloadedStrings #-}

module CoinbasePro.WebSocketFeed.Channel
  ( ChannelMessage (..)
  ) where

import           Data.Aeson                                      (FromJSON (..),
                                                                  Value (..),
                                                                  withObject,
                                                                  (.:))

import           CoinbasePro.WebSocketFeed.Channel.Full.Activate (Activate (..))
import           CoinbasePro.WebSocketFeed.Channel.Full.Change   (Change (..))
import           CoinbasePro.WebSocketFeed.Channel.Full.Done     (Done (..))
import           CoinbasePro.WebSocketFeed.Channel.Full.Match    (Match (..))
import           CoinbasePro.WebSocketFeed.Channel.Full.Open     (Open (..))
import           CoinbasePro.WebSocketFeed.Channel.Full.Received (Received (..))
import           CoinbasePro.WebSocketFeed.Channel.Heartbeat     (Heartbeat (..))
import           CoinbasePro.WebSocketFeed.Channel.Level2        (L2Update (..),
                                                                  Snapshot (..))
import qualified CoinbasePro.WebSocketFeed.Channel.Level2        as L2
import           CoinbasePro.WebSocketFeed.Channel.Status        (Status (..))
import           CoinbasePro.WebSocketFeed.Channel.Ticker        (Ticker (..))
import           CoinbasePro.WebSocketFeed.Response              (Subscription)


data ChannelMessage =
      ActivateMessage Activate
    | ChangeMessage Change
    | DoneMessage Done
    | HeartbeatMessage Heartbeat
    | StatusMessage Status
    | L2ChangeMessage L2.Change
    | L2SnapshotMessage Snapshot
    | L2UpdateMessage L2Update
    | MatchMessage Match
    | OpenMessage Open
    | ReceivedMessage Received
    | TickerMessage Ticker
    | SubscriptionMessage Subscription
    deriving (Int -> ChannelMessage -> ShowS
[ChannelMessage] -> ShowS
ChannelMessage -> String
(Int -> ChannelMessage -> ShowS)
-> (ChannelMessage -> String)
-> ([ChannelMessage] -> ShowS)
-> Show ChannelMessage
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ChannelMessage] -> ShowS
$cshowList :: [ChannelMessage] -> ShowS
show :: ChannelMessage -> String
$cshow :: ChannelMessage -> String
showsPrec :: Int -> ChannelMessage -> ShowS
$cshowsPrec :: Int -> ChannelMessage -> ShowS
Show, ChannelMessage -> ChannelMessage -> Bool
(ChannelMessage -> ChannelMessage -> Bool)
-> (ChannelMessage -> ChannelMessage -> Bool) -> Eq ChannelMessage
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ChannelMessage -> ChannelMessage -> Bool
$c/= :: ChannelMessage -> ChannelMessage -> Bool
== :: ChannelMessage -> ChannelMessage -> Bool
$c== :: ChannelMessage -> ChannelMessage -> Bool
Eq)


instance FromJSON ChannelMessage where
    parseJSON :: Value -> Parser ChannelMessage
parseJSON = String
-> (Object -> Parser ChannelMessage)
-> Value
-> Parser ChannelMessage
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"channel message" ((Object -> Parser ChannelMessage)
 -> Value -> Parser ChannelMessage)
-> (Object -> Parser ChannelMessage)
-> Value
-> Parser ChannelMessage
forall a b. (a -> b) -> a -> b
$ \Object
o -> do
        Value
t <- Text -> Value
String (Text -> Value) -> Parser Text -> Parser Value
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
"type"
        case Value
t of
          Value
"activate"      -> Activate -> ChannelMessage
ActivateMessage (Activate -> ChannelMessage)
-> Parser Activate -> Parser ChannelMessage
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser Activate
forall a. FromJSON a => Value -> Parser a
parseJSON (Object -> Value
Object Object
o)
          Value
"change"        -> Change -> ChannelMessage
ChangeMessage (Change -> ChannelMessage)
-> Parser Change -> Parser ChannelMessage
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser Change
forall a. FromJSON a => Value -> Parser a
parseJSON (Object -> Value
Object Object
o)
          Value
"done"          -> Done -> ChannelMessage
DoneMessage (Done -> ChannelMessage) -> Parser Done -> Parser ChannelMessage
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser Done
forall a. FromJSON a => Value -> Parser a
parseJSON (Object -> Value
Object Object
o)
          Value
"heartbeat"     -> Heartbeat -> ChannelMessage
HeartbeatMessage (Heartbeat -> ChannelMessage)
-> Parser Heartbeat -> Parser ChannelMessage
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser Heartbeat
forall a. FromJSON a => Value -> Parser a
parseJSON (Object -> Value
Object Object
o)
          Value
"status"        -> Status -> ChannelMessage
StatusMessage (Status -> ChannelMessage)
-> Parser Status -> Parser ChannelMessage
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser Status
forall a. FromJSON a => Value -> Parser a
parseJSON (Object -> Value
Object Object
o)
          Value
"l2update"      -> L2Update -> ChannelMessage
L2UpdateMessage (L2Update -> ChannelMessage)
-> Parser L2Update -> Parser ChannelMessage
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser L2Update
forall a. FromJSON a => Value -> Parser a
parseJSON (Object -> Value
Object Object
o)
          Value
"last_match"    -> Match -> ChannelMessage
MatchMessage (Match -> ChannelMessage) -> Parser Match -> Parser ChannelMessage
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser Match
forall a. FromJSON a => Value -> Parser a
parseJSON (Object -> Value
Object Object
o)
          Value
"match"         -> Match -> ChannelMessage
MatchMessage (Match -> ChannelMessage) -> Parser Match -> Parser ChannelMessage
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser Match
forall a. FromJSON a => Value -> Parser a
parseJSON (Object -> Value
Object Object
o)
          Value
"open"          -> Open -> ChannelMessage
OpenMessage (Open -> ChannelMessage) -> Parser Open -> Parser ChannelMessage
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser Open
forall a. FromJSON a => Value -> Parser a
parseJSON (Object -> Value
Object Object
o)
          Value
"received"      -> Received -> ChannelMessage
ReceivedMessage (Received -> ChannelMessage)
-> Parser Received -> Parser ChannelMessage
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser Received
forall a. FromJSON a => Value -> Parser a
parseJSON (Object -> Value
Object Object
o)
          Value
"snapshot"      -> Snapshot -> ChannelMessage
L2SnapshotMessage (Snapshot -> ChannelMessage)
-> Parser Snapshot -> Parser ChannelMessage
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser Snapshot
forall a. FromJSON a => Value -> Parser a
parseJSON (Object -> Value
Object Object
o)
          Value
"subscriptions" -> Subscription -> ChannelMessage
SubscriptionMessage (Subscription -> ChannelMessage)
-> Parser Subscription -> Parser ChannelMessage
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser Subscription
forall a. FromJSON a => Value -> Parser a
parseJSON (Object -> Value
Object Object
o)
          Value
"ticker"        -> Ticker -> ChannelMessage
TickerMessage (Ticker -> ChannelMessage)
-> Parser Ticker -> Parser ChannelMessage
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser Ticker
forall a. FromJSON a => Value -> Parser a
parseJSON (Object -> Value
Object Object
o)
          Value
_               -> String -> Parser ChannelMessage
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Unable to parse channel message"