module Logging.Utils
  ( addZonedTime
  , diffZonedTime
  , zonedTimeToPOSIXSeconds
  , timestamp
  , seconds
  , milliseconds
  , microseconds
  , openLogFile
  , rotateFile
  , modifyBaseName
  ) where

import           Control.Monad
import           Data.Time.Clock
import           Data.Time.Clock.POSIX
import           Data.Time.LocalTime
import           System.Directory
import           System.Environment
import           System.FilePath
import           System.IO


addZonedTime :: NominalDiffTime -> ZonedTime -> ZonedTime
addZonedTime ndt zt@(ZonedTime _ tz) =
  utcToZonedTime tz $ addUTCTime ndt $ zonedTimeToUTC zt


diffZonedTime :: ZonedTime -> ZonedTime -> NominalDiffTime
diffZonedTime zt1 zt2 = diffUTCTime (zonedTimeToUTC zt1) (zonedTimeToUTC zt2)


zonedTimeToPOSIXSeconds :: ZonedTime -> NominalDiffTime
zonedTimeToPOSIXSeconds = utcTimeToPOSIXSeconds . zonedTimeToUTC


timestamp :: NominalDiffTime -> Double
timestamp = fromRational . toRational


seconds :: NominalDiffTime -> Integer
seconds = truncate


milliseconds :: NominalDiffTime -> Integer
milliseconds = truncate . (* 1000)


microseconds :: NominalDiffTime -> Integer
microseconds = truncate . (* 1000000)


openLogFile :: FilePath -> TextEncoding -> IO Handle
openLogFile path encoding = do
  absPath <- makeAbsolute path
  progName <- getProgName
  let dir = takeDirectory absPath
      file = if dir == absPath then dir </> (progName ++ ".log") else absPath
  createDirectoryIfMissing True dir
  stream <- openFile file AppendMode
  hSetEncoding stream encoding
  return stream


rotateFile :: FilePath -> FilePath -> IO ()
rotateFile src dest = doesFileExist src >>= (flip when $ renameFile src dest)


modifyBaseName :: FilePath -> (String -> String) -> FilePath
modifyBaseName file modify = replaceBaseName file $ modify $ takeBaseName file