module Network.Mux.Time
  ( -- * DiffTime
    DiffTime
  , diffTimeToMicroseconds
  , microsecondsToDiffTime
    -- * Compact timestamp
  , timestampMicrosecondsLow32Bits
  ) where

import Control.Monad.Class.MonadTime.SI (Time (..))
import Data.Time.Clock (DiffTime, diffTimeToPicoseconds, picosecondsToDiffTime)
import Data.Word (Word32)

diffTimeToMicroseconds :: DiffTime -> Integer
diffTimeToMicroseconds :: DiffTime -> Integer
diffTimeToMicroseconds = (Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Integer
1000000) (Integer -> Integer)
-> (DiffTime -> Integer) -> DiffTime -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DiffTime -> Integer
diffTimeToPicoseconds

microsecondsToDiffTime :: Integer -> DiffTime
microsecondsToDiffTime :: Integer -> DiffTime
microsecondsToDiffTime = Integer -> DiffTime
picosecondsToDiffTime (Integer -> DiffTime)
-> (Integer -> Integer) -> Integer -> DiffTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1000000)

-- | This is a slightly peculiar operation: it returns the number of
-- microseconds since an arbitrary epoch, modulo 2^32. This number of
-- microseconds wraps every ~35 minutes.
--
-- The purpose is to give a compact timestamp (compact to send over the wire)
-- for measuring time differences on the order of seconds or less.
--
timestampMicrosecondsLow32Bits :: Time -> Word32
timestampMicrosecondsLow32Bits :: Time -> Word32
timestampMicrosecondsLow32Bits (Time DiffTime
ts) =
    Integer -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (DiffTime -> Integer
diffTimeToMicroseconds DiffTime
ts)