{-# LANGUAGE DeriveGeneric         #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE RecordWildCards       #-}

module Logging.Types.Handlers.FileHandler
  ( FileHandler(..)
  ) where

import           Data.IORef
import           GHC.Generics
import           System.IO

import           Logging.Types.Class
import           Logging.Types.Filter
import           Logging.Types.Formatter
import           Logging.Types.Level
import           Logging.Utils
import           System.IO.Extra


-- | A handler type which writes logging records, appropriately formatted,
-- to a file.
--
data FileHandler = FileHandler { stream    :: IORef Handle
                               , file      :: FilePath
                               , encoding  :: TextEncoding
                               , level     :: Level
                               , filterer  :: Filterer
                               , formatter :: Formatter
                               } deriving (Generic, Eq)

instance Handler FileHandler where
  open FileHandler{..} = atomicWriteIORef stream =<< openLogFile file encoding

  emit self@FileHandler{..} rcd = do
    flip hPutStrLn (format formatter rcd) =<< readIORef stream
    flush self

  flush FileHandler{..}= hFlush =<< readIORef stream

  close FileHandler{..} = hClose =<< readIORef stream