-- | A simple system so that the Cryptol driver can communicate
-- with users (or not).
module Cryptol.Utils.Logger
  ( Logger

  , stdoutLogger
  , stderrLogger
  , handleLogger
  , quietLogger
  , funLogger

  , logPutStr
  , logPutStrLn
  , logPrint
  ) where

import System.IO(Handle, hPutStr, stdout, stderr)
import Control.DeepSeq(NFData(..))

-- | A logger provides simple abstraction for sending messages.
newtype Logger = Logger (String -> IO ())

instance NFData Logger where
  rnf (Logger x) = rnf x

-- | Send the given string to the log.
logPutStr :: Logger -> String -> IO ()
logPutStr (Logger f) = f

-- | Send the given string with a newline at the end.
logPutStrLn :: Logger -> String -> IO ()
logPutStrLn l s = logPutStr l (s ++ "\n")

-- | Send the given value using its 'Show' instance.
-- Adds a newline at the end.
logPrint :: Show a => Logger -> a -> IO ()
logPrint l a = logPutStrLn l (show a)

-- | A logger that ignores all messages.
quietLogger :: Logger
quietLogger = Logger (const (return ()))

-- | Log to the given handle.
handleLogger :: Handle -> Logger
handleLogger h = Logger (hPutStr h)

-- | Log to stdout.
stdoutLogger :: Logger
stdoutLogger = handleLogger stdout

-- | Log to stderr.
stderrLogger :: Logger
stderrLogger = handleLogger stderr

-- | Just use this function for logging.
funLogger :: (String -> IO ()) -> Logger
funLogger = Logger