{-# Language DeriveGeneric #-}

--------------------------------------------------------------------
-- |
-- Module: HTrade.Shared.Types
--
-- Types shared between the different projects.
-- Contains shared definitions related to backend<->proxy communication.

module HTrade.Shared.Types where

import qualified Data.ByteString.Char8           as B
import           Data.Binary                     (Binary)
import           Data.Int                        (Int64)
import           Data.Word                       (Word64)
import           GHC.Generics                    (Generic)

-- | Current version of proxy software, major and minor versions.
type ProxyVersion = (Int, Int)

-- | Serialized trades used in backend<->proxy communication.
type TradesSerialized = B.ByteString

-- | Serialized order book used in backend<->proxy communication.
type OrderBookSerialized = B.ByteString

-- | Identifier of a single trade on some market.
type TradeID = Int64

-- | Request from backend to a proxy node.
data ProxyRequest
 -- | Request market data.
 = MarketRequest
   {
     _targetSite              :: B.ByteString,            -- ^ Site to be requested e.g. http(s):\/\/site.com.
     _targetPath              :: B.ByteString,            -- ^ Path shared by order book and trades e.g. sub\/dir.
     _targetTradePath         :: B.ByteString,            -- ^ Path to trades JSON file e.g. orderbook.
     _targetOrderBookPath     :: B.ByteString,            -- ^ Path to order book JSON file e.g. trades.
     _timeout                 :: MicroSeconds,            -- ^ Timeout before the proxy should send a response.
     _tradeID                 :: TradeID                  -- ^ ID of last trade successfully retrieved.
   }
 -- | Request status of proxy node.
 | StatusRequest
   {
   }
 -- | Issue request to reload parts of the proxy node.
 | ReloadRequest
   {
     _performUpgrade          :: Bool,                    -- ^ True if the proxy node should upgrade its software.
     _reboot                  :: Bool                     -- ^ True if the proxy node should reboot.
   }
 deriving (Eq, Generic, Show)

instance Binary ProxyRequest

-- | Response generated by proxy node, sent to backend.
data ProxyResponse
 -- | Reply containing market data, regardless if the market actually replied.
 = MarketReply
   {
     _marketReply             :: Maybe MarketReplyDetails -- ^ Market reply, if available.
   }
 -- | Reply containing status of the proxy node.
 | StatusReply
   {
     _version                 :: !ProxyVersion,           -- ^ Version running on the proxy node.
     _memLoad                 :: !Double,                 -- ^ Current allocated memory in [0,1].
     _cpuLoad                 :: !Double,                 -- ^ Current CPU load in [0,1].
     _responseMean            :: !Double,                 -- ^ Mean response time across all requests.
     _responseStd             :: !Double                  -- ^ Standard deviation of response times.
   }
 -- | Simple acknowledgement indicating that the request was retrieved and processed.
 | AcknowledgementReply
   {
   }
 deriving (Eq, Generic, Show)

instance Binary ProxyResponse

-- | Details related to fetching market data.
data MarketReplyDetails
 -- | Contents related to a response from a market.
 = MarketReplyDetails
   {
     _responseTime            :: MicroSeconds,            -- ^ Elapsed time until complete response was retrieved.
     _responseTimestamp       :: Word64,                  -- ^ POSIX timestamp (second resolution) taken after all data was received.
     _trades                  :: TradesSerialized,        -- ^ Serialized (possibly empty) list of trades.
     _orderBook               :: OrderBookSerialized      -- ^ Serialized (possibly empty) order book.
   }
 deriving (Eq, Generic, Show)

instance Binary MarketReplyDetails

-- | Microseconds alias used for clarity.
type MicroSeconds = Word64

-- | Response time in microseconds when polling a market.
type ResponseTime = Int
