{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Cardano.RTView.NodeState.Parsers
    ( extractPeersInfo
    ) where

import           Cardano.Prelude

import           Data.Aeson (Object, (.:))
import qualified Data.Aeson as A
import qualified Data.Text as T

import           Cardano.RTView.NodeState.Types (PeerInfo (..))

extractPeersInfo :: Object -> [PeerInfo]
extractPeersInfo :: Object -> [PeerInfo]
extractPeersInfo Object
peersObj =
  case Result ConnectedPeers
result of
    A.Success (ConnectedPeers [ConnectedPeer]
cPeers) ->
      ((ConnectedPeer -> PeerInfo) -> [ConnectedPeer] -> [PeerInfo])
-> [ConnectedPeer] -> (ConnectedPeer -> PeerInfo) -> [PeerInfo]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (ConnectedPeer -> PeerInfo) -> [ConnectedPeer] -> [PeerInfo]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map [ConnectedPeer]
cPeers ((ConnectedPeer -> PeerInfo) -> [PeerInfo])
-> (ConnectedPeer -> PeerInfo) -> [PeerInfo]
forall a b. (a -> b) -> a -> b
$ \ConnectedPeer
p ->
        PeerInfo :: String
-> String -> String -> String -> String -> String -> PeerInfo
PeerInfo
          { piEndpoint :: String
piEndpoint   = Text -> String
T.unpack (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ ConnectedPeer -> Text
peerAddress ConnectedPeer
p
          , piBytesInF :: String
piBytesInF   = Text -> String
T.unpack (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ ConnectedPeer -> Text
peerBytesInF ConnectedPeer
p
          , piReqsInF :: String
piReqsInF    = Text -> String
T.unpack (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ ConnectedPeer -> Text
peerReqsInF ConnectedPeer
p
          , piBlocksInF :: String
piBlocksInF  = Text -> String
T.unpack (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ ConnectedPeer -> Text
peerBlocksInF ConnectedPeer
p
          , piSlotNumber :: String
piSlotNumber = Text -> String
T.unpack (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ ConnectedPeer -> Text
peerSlotNo ConnectedPeer
p
          , piStatus :: String
piStatus     = Text -> String
T.unpack (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ ConnectedPeer -> Text
peerStatus ConnectedPeer
p
          }
    A.Error String
_ -> []
 where
  result :: A.Result ConnectedPeers
  result :: Result ConnectedPeers
result = Value -> Result ConnectedPeers
forall a. FromJSON a => Value -> Result a
A.fromJSON (Value -> Result ConnectedPeers) -> Value -> Result ConnectedPeers
forall a b. (a -> b) -> a -> b
$ Object -> Value
A.Object Object
peersObj

-- Types for decoding from JSON-representation.

newtype ConnectedPeers = ConnectedPeers [ConnectedPeer]

data ConnectedPeer
  = ConnectedPeer
      { ConnectedPeer -> Text
peerBytesInF  :: !Text
      , ConnectedPeer -> Text
peerReqsInF   :: !Text
      , ConnectedPeer -> Text
peerBlocksInF :: !Text
      , ConnectedPeer -> Text
peerAddress   :: !Text
      , ConnectedPeer -> Text
peerSlotNo    :: !Text
      , ConnectedPeer -> Text
peerStatus    :: !Text
      }

instance A.FromJSON ConnectedPeers where
  parseJSON :: Value -> Parser ConnectedPeers
parseJSON = String
-> (Object -> Parser ConnectedPeers)
-> Value
-> Parser ConnectedPeers
forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject String
"ConnectedPeers" ((Object -> Parser ConnectedPeers)
 -> Value -> Parser ConnectedPeers)
-> (Object -> Parser ConnectedPeers)
-> Value
-> Parser ConnectedPeers
forall a b. (a -> b) -> a -> b
$ \Object
v -> [ConnectedPeer] -> ConnectedPeers
ConnectedPeers
    ([ConnectedPeer] -> ConnectedPeers)
-> Parser [ConnectedPeer] -> Parser ConnectedPeers
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
v Object -> Text -> Parser [ConnectedPeer]
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"peers"

instance A.FromJSON ConnectedPeer where
  parseJSON :: Value -> Parser ConnectedPeer
parseJSON = String
-> (Object -> Parser ConnectedPeer)
-> Value
-> Parser ConnectedPeer
forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject String
"ConnectedPeer" ((Object -> Parser ConnectedPeer) -> Value -> Parser ConnectedPeer)
-> (Object -> Parser ConnectedPeer)
-> Value
-> Parser ConnectedPeer
forall a b. (a -> b) -> a -> b
$ \Object
v -> Text -> Text -> Text -> Text -> Text -> Text -> ConnectedPeer
ConnectedPeer
    (Text -> Text -> Text -> Text -> Text -> Text -> ConnectedPeer)
-> Parser Text
-> Parser (Text -> Text -> Text -> Text -> Text -> ConnectedPeer)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
v Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"peerBytesInF"
    Parser (Text -> Text -> Text -> Text -> Text -> ConnectedPeer)
-> Parser Text
-> Parser (Text -> Text -> Text -> Text -> ConnectedPeer)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"peerReqsInF"
    Parser (Text -> Text -> Text -> Text -> ConnectedPeer)
-> Parser Text -> Parser (Text -> Text -> Text -> ConnectedPeer)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"peerBlocksInF"
    Parser (Text -> Text -> Text -> ConnectedPeer)
-> Parser Text -> Parser (Text -> Text -> ConnectedPeer)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"peerAddress"
    Parser (Text -> Text -> ConnectedPeer)
-> Parser Text -> Parser (Text -> ConnectedPeer)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"peerSlotNo"
    Parser (Text -> ConnectedPeer)
-> Parser Text -> Parser ConnectedPeer
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"peerStatus"