{-# LANGUAGE ExistentialQuantification #-}
{-|
    Module      :  Control.ERNet.Foundations.Event
    Description :  communication events
    Copyright   :  (c) Michal Konecny
    License     :  BSD3

    Maintainer  :  mik@konecny.aow.cz
    Stability   :  experimental
    Portability :  portable

    Communication events with various data useful for logging
    and debugging.  
-}
module Control.ERNet.Foundations.Event where

import Control.ERNet.Foundations.Protocol

import Data.Time.Clock

{-|
    Data to be logged with every query and answer event.
-}
data ERNetEvent 
    =
      forall q a. (QAProtocol q a, Show q, Show a) =>
      ERNetEvQryMade
        {
            ernetevTime :: UTCTime,
            ernetevQryId :: QueryId,
            ernetevFromId :: String,
            ernetevFromQryId :: QueryId,
            ernetevToId :: String,
            ernetevQry :: q
        }
    | forall q a. (QAProtocol q a, Show q, Show a) =>
      ERNetEvQryReceived
        {
            ernetevTime :: UTCTime,
            ernetevQryId :: QueryId,
            ernetevToId :: String,
            ernetevQry :: q
        }
    | forall q a. (QAProtocol q a, Show q, Show a) =>
      ERNetEvAnsMade
        {
            ernetevTime :: UTCTime,
            ernetevQryId :: QueryId,
            ernetevToId :: String, -- ^ query target, the one who answered
            ernetevAns :: a
        }
    | forall q a. (QAProtocol q a, Show q, Show a) =>
      ERNetEvAnsReceived
        {
            ernetevTime :: UTCTime,
            ernetevQryId :: QueryId,
            ernetevFromId :: String, -- ^ query originator, receiver of answer
            ernetevFromQryId :: QueryId,
            ernetevToId :: String, -- ^ query target, the one who answered
            ernetevAns :: a,
            ernetevQry :: q
        }
        
instance Show ERNetEvent where
    show (ERNetEvQryMade time qryId from fromQryId to qry) =
        "Q{" ++ (showNQ from fromQryId) ++ " --?-> " ++ (showNQ to qryId) ++ "}\n      " ++ show qry
    show (ERNetEvQryReceived time qryId to qry) =
        "QR:" ++ to ++ ": got query " ++ show qryId
    show (ERNetEvAnsMade time qryId to ans) =
        "A:" ++ (showNQ to qryId) ++ ": " ++ show ans
    show (ERNetEvAnsReceived time qryId from fromQryId to ans qry) =
        "A{" ++ (showNQ from fromQryId) ++ " <-!-- " ++ (showNQ to qryId) ++ "}\n      " ++ 
        show qry ++ "\n ===> " ++ show ans

showNQ procName qryId = procName ++ "." ++ (show qryId)