{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes       #-}
{-# LANGUAGE TemplateHaskell   #-}

{-| This module provides a series of log routines that create a 'LogRecord'
 and then emit a log event.

The log routines use "Language.Haskell.TH" to obtain some fields related to
where they are called,
e.g. __filename__, __pkgname__, __modulename__, __lineno__

When use these log routines, you should enable __TemplateHaskell__
language extension.
-}

module Logging.Monad.TH
  ( logv
  , debug
  , info
  , warn
  , error
  , fatal
  ) where

import           Control.Monad.IO.Class (MonadIO)
import           Language.Haskell.TH

import           Logging.Monad.Internal
import           Logging.Types

import           Prelude                hiding (error, log)

-- | Log "message" with the severity "level".
--
-- The missing type signature:
-- 'MonadIO' m => 'Logger' -> 'Level' -> 'String' -> 'LoggingT' m ()
logv :: ExpQ
logv = do
  loc <- location
  let filename = loc_filename loc
      packagename = loc_package loc
      modulename = loc_module loc
      lineno = fst $ loc_start loc
      location = (filename, packagename, modulename, lineno)
  [| \logger level msg -> log logger level msg location |]

-- | Log "message" with a specific severity.
--
-- The missing type signature:
-- 'MonadIO' m => 'Logger' -> 'String' -> 'LoggingT' m ()
debug, info, warn, error, fatal :: ExpQ
debug = [| \logger -> $(logv) logger $ read "DEBUG" |]
info  = [| \logger -> $(logv) logger $ read "INFO" |]
warn  = [| \logger -> $(logv) logger $ read "WARN" |]
error = [| \logger -> $(logv) logger $ read "ERROR" |]
fatal = [| \logger -> $(logv) logger $ read "FATAL" |]