{-# LANGUAGE CPP #-}

module Blammo.Logging.Test
  ( LoggedMessages
  , LoggedMessage(..)
  , newLoggedMessages
  , appendLogStr
  , appendLogStrLn
  , getLoggedMessages
  ) where

import Prelude

import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad.Logger.Aeson (LoggedMessage(..))
import Data.Aeson (eitherDecodeStrict)
import Data.DList (DList)
import qualified Data.DList as DList
import System.Log.FastLogger (LogStr, fromLogStr)
import UnliftIO.IORef

newtype LoggedMessages = LoggedMessages
  { LoggedMessages -> IORef (DList LogStr)
_unLoggedMessages :: IORef (DList LogStr)
  }

newLoggedMessages :: MonadIO m => m LoggedMessages
newLoggedMessages :: forall (m :: * -> *). MonadIO m => m LoggedMessages
newLoggedMessages = IORef (DList LogStr) -> LoggedMessages
LoggedMessages forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. MonadIO m => a -> m (IORef a)
newIORef forall a. DList a
DList.empty

appendLogStr :: MonadIO m => LoggedMessages -> LogStr -> m ()
appendLogStr :: forall (m :: * -> *). MonadIO m => LoggedMessages -> LogStr -> m ()
appendLogStr (LoggedMessages IORef (DList LogStr)
ref) LogStr
str =
  forall (m :: * -> *) a b.
MonadIO m =>
IORef a -> (a -> (a, b)) -> m b
atomicModifyIORef' IORef (DList LogStr)
ref forall a b. (a -> b) -> a -> b
$ \DList LogStr
x -> (forall a. DList a -> a -> DList a
DList.snoc DList LogStr
x LogStr
str, ())

appendLogStrLn :: MonadIO m => LoggedMessages -> LogStr -> m ()
appendLogStrLn :: forall (m :: * -> *). MonadIO m => LoggedMessages -> LogStr -> m ()
appendLogStrLn LoggedMessages
lm = forall (m :: * -> *). MonadIO m => LoggedMessages -> LogStr -> m ()
appendLogStr LoggedMessages
lm forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. Semigroup a => a -> a -> a
<> LogStr
"\n")

getLoggedMessages :: MonadIO m => LoggedMessages -> m [Either String LoggedMessage]
getLoggedMessages :: forall (m :: * -> *).
MonadIO m =>
LoggedMessages -> m [Either String LoggedMessage]
getLoggedMessages (LoggedMessages IORef (DList LogStr)
ref) =
  forall a b. (a -> b) -> [a] -> [b]
map (forall a. FromJSON a => ByteString -> Either String a
eitherDecodeStrict forall b c a. (b -> c) -> (a -> b) -> a -> c
. LogStr -> ByteString
fromLogStr) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. DList a -> [a]
DList.toList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. MonadIO m => IORef a -> m a
readIORef IORef (DList LogStr)
ref