module Simulation.Aivika.Distributed.Optimistic.Internal.Message
       (Message(..),
        antiMessage,
        antiMessages,
        AcknowledgementMessage(..),
        acknowledgementMessage,
        LogicalProcessMessage(..),
        TimeServerMessage(..),
        InboxProcessMessage(..),
        KeepAliveMessage(..)) where
import GHC.Generics
import Data.Typeable
import Data.Binary
import qualified Control.Distributed.Process as DP
import Control.Distributed.Process.Serializable
import Simulation.Aivika.Distributed.Optimistic.State
data Message =
  Message { messageSequenceNo :: Int,
            
            messageSendTime :: Double,
            
            messageReceiveTime :: Double,
            
            messageSenderId :: DP.ProcessId,
            
            messageReceiverId :: DP.ProcessId,
            
            messageAntiToggle :: Bool,
            
            messageData :: DP.Message
            
          } deriving (Show, Typeable, Generic)
instance Binary Message
antiMessage :: Message -> Message
antiMessage x = x { messageAntiToggle = not (messageAntiToggle x) }
antiMessages :: Message -> Message -> Bool
antiMessages x y =
  (messageSequenceNo x == messageSequenceNo y) &&
  (messageSendTime x == messageSendTime y) &&
  (messageReceiveTime x == messageReceiveTime y) &&
  (messageSenderId x == messageSenderId y) &&
  (messageReceiverId x == messageReceiverId y) &&
  (messageAntiToggle x /= messageAntiToggle y)
instance Eq Message where
  x == y =
    (messageSequenceNo x == messageSequenceNo y) &&
    (messageSendTime x == messageSendTime y) &&
    (messageReceiveTime x == messageReceiveTime y) &&
    (messageSenderId x == messageSenderId y) &&
    (messageReceiverId x == messageReceiverId y) &&
    (messageAntiToggle x == messageAntiToggle y)
data AcknowledgementMessage =
  AcknowledgementMessage { acknowledgementSequenceNo :: Int,
                           
                           acknowledgementSendTime :: Double,
                           
                           acknowledgementReceiveTime :: Double,
                           
                           acknowledgementSenderId :: DP.ProcessId,
                           
                           acknowledgementReceiverId :: DP.ProcessId,
                           
                           acknowledgementAntiToggle :: Bool,
                           
                           acknowledgementMarked :: Bool
                           
                         } deriving (Eq, Ord, Show, Typeable, Generic)
instance Binary AcknowledgementMessage
acknowledgementMessage :: Bool -> Message -> AcknowledgementMessage
acknowledgementMessage marked x =
  AcknowledgementMessage { acknowledgementSequenceNo = messageSequenceNo x,
                           acknowledgementSendTime = messageSendTime x,
                           acknowledgementReceiveTime = messageReceiveTime x,
                           acknowledgementSenderId = messageSenderId x,
                           acknowledgementReceiverId = messageReceiverId x,
                           acknowledgementAntiToggle = messageAntiToggle x,
                           acknowledgementMarked = marked
                         }
data LogicalProcessMessage = QueueMessage Message
                             
                           | QueueMessageBulk [Message]
                             
                           | AcknowledgementQueueMessage AcknowledgementMessage
                             
                           | AcknowledgementQueueMessageBulk [AcknowledgementMessage]
                             
                           | ComputeLocalTimeMessage
                             
                           | GlobalTimeMessage Double
                             
                           | ProcessMonitorNotificationMessage DP.ProcessMonitorNotification
                             
                           | ReconnectProcessMessage DP.ProcessId
                             
                           | ProvideLogicalProcessStateMessage DP.ProcessId
                             
                           | AbortSimulationMessage
                             
                           deriving (Show, Typeable, Generic)
instance Binary LogicalProcessMessage
data TimeServerMessage = RegisterLogicalProcessMessage DP.ProcessId
                         
                       | UnregisterLogicalProcessMessage DP.ProcessId
                         
                       | TerminateTimeServerMessage DP.ProcessId
                         
                       | ComputeLocalTimeAcknowledgementMessage DP.ProcessId
                         
                       | RequestGlobalTimeMessage DP.ProcessId
                         
                       | LocalTimeMessage DP.ProcessId Double
                         
                       | ProvideTimeServerStateMessage DP.ProcessId
                         
                       | ReMonitorTimeServerMessage [DP.ProcessId]
                         
                       deriving (Eq, Show, Typeable, Generic)
instance Binary TimeServerMessage
data InboxProcessMessage = MonitorProcessMessage DP.ProcessId
                           
                         | ReMonitorProcessMessage [DP.ProcessId]
                           
                         | TrySendKeepAliveMessage
                           
                         | SendQueueMessage DP.ProcessId Message
                           
                         | SendQueueMessageBulk DP.ProcessId [Message]
                           
                         | SendAcknowledgementQueueMessage DP.ProcessId AcknowledgementMessage
                           
                         | SendAcknowledgementQueueMessageBulk DP.ProcessId [AcknowledgementMessage]
                           
                         | SendLocalTimeMessage DP.ProcessId DP.ProcessId Double
                           
                         | SendRequestGlobalTimeMessage DP.ProcessId DP.ProcessId
                           
                         | SendRegisterLogicalProcessMessage DP.ProcessId DP.ProcessId
                           
                         | SendUnregisterLogicalProcessMessage DP.ProcessId DP.ProcessId
                           
                         | SendTerminateTimeServerMessage DP.ProcessId DP.ProcessId
                           
                         | RegisterLogicalProcessAcknowledgementMessage DP.ProcessId
                           
                         | UnregisterLogicalProcessAcknowledgementMessage DP.ProcessId
                           
                         | TerminateTimeServerAcknowledgementMessage DP.ProcessId
                           
                         | TerminateInboxProcessMessage
                           
                         deriving (Eq, Show, Typeable, Generic)
instance Binary InboxProcessMessage
data KeepAliveMessage = KeepAliveMessage
                        
                        deriving (Eq, Show, Typeable, Generic)
instance Binary KeepAliveMessage