-- |The data type 'Event' consists of a yank text and metadata identifying its source and time.
module Helic.Data.Event where

import qualified Chronos
import Polysemy.Chronos (ChronosTime)
import qualified Polysemy.Time as Time

import Helic.Data.AgentId (AgentId)
import Helic.Data.InstanceName (InstanceName)
import Exon (exon)

-- |The central data type representing a clipboard event.
data Event =
  Event {
    -- |The host from which the event originated.
    Event -> InstanceName
sender :: InstanceName,
    -- |The entity that caused the event.
    Event -> AgentId
source :: AgentId,
    -- |Timestamp.
    Event -> Time
time :: Chronos.Time,
    -- |Payload.
    Event -> Text
content :: Text
  }
  deriving stock (Event -> Event -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Event -> Event -> Bool
$c/= :: Event -> Event -> Bool
== :: Event -> Event -> Bool
$c== :: Event -> Event -> Bool
Eq, Int -> Event -> ShowS
[Event] -> ShowS
Event -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Event] -> ShowS
$cshowList :: [Event] -> ShowS
show :: Event -> String
$cshow :: Event -> String
showsPrec :: Int -> Event -> ShowS
$cshowsPrec :: Int -> Event -> ShowS
Show)

json ''Event

-- |Construct an event for the current host and time.
now ::
  Members [ChronosTime, Reader InstanceName] r =>
  AgentId ->
  Text ->
  Sem r Event
now :: forall (r :: EffectRow).
Members '[ChronosTime, Reader InstanceName] r =>
AgentId -> Text -> Sem r Event
now AgentId
source Text
content = do
  InstanceName
sender <- forall i (r :: EffectRow). Member (Reader i) r => Sem r i
ask
  Time
time <- forall t d (r :: EffectRow). Member (Time t d) r => Sem r t
Time.now
  pure Event {Text
Time
AgentId
InstanceName
time :: Time
sender :: InstanceName
content :: Text
source :: AgentId
$sel:content:Event :: Text
$sel:time:Event :: Time
$sel:source:Event :: AgentId
$sel:sender:Event :: InstanceName
..}

describe :: Event -> Text
describe :: Event -> Text
describe Event {Text
Time
AgentId
InstanceName
content :: Text
time :: Time
source :: AgentId
sender :: InstanceName
$sel:content:Event :: Event -> Text
$sel:time:Event :: Event -> Time
$sel:source:Event :: Event -> AgentId
$sel:sender:Event :: Event -> InstanceName
..} =
  [exon|##{sender}:##{source}|]