module Vaultaire.Program
(
    initializeProgram,
    Verbosity(..)
)
where
import Control.Concurrent.MVar
import Control.Monad
import GHC.Conc
import System.Environment
import System.IO (hFlush, hPutStrLn, stdout)
import System.Log.Formatter
import System.Log.Handler (setFormatter)
import System.Log.Handler.Simple
import System.Log.Logger
import System.Posix.Signals
interruptHandler :: MVar () -> Handler
interruptHandler semaphore = Catch $ do
    putStrLn "\nInterrupt"
    hFlush stdout
    putMVar semaphore ()
terminateHandler :: MVar () -> Handler
terminateHandler semaphore = Catch $ do
    putStrLn "Terminating"
    hFlush stdout
    putMVar semaphore ()
quitHandler :: Handler
quitHandler = Catch $ do
    putStrLn ""
    hFlush stdout
    logger <- getLogger rootLoggerName
    let level   = getLevel logger
        level'  = case level of
                    Just DEBUG  -> INFO
                    Just INFO   -> DEBUG
                    _           -> DEBUG
        logger' = setLevel level' logger
    saveGlobalLogger logger'
    infoM "Main.quitHandler" ("Change log level to " ++ show level')
data Verbosity = Debug | Normal | Quiet deriving Show
initializeProgram :: String -> Verbosity -> IO (MVar ())
initializeProgram banner verbosity = do
    
    name <- getProgName
    case verbosity of
        Quiet -> return ()
        _     -> putStrLn $ name ++ " (" ++ banner ++ ") starting"
    
    when (numCapabilities == 1) (getNumProcessors >>= setNumCapabilities)
    
    
    setEnv "TZ" "UTC"
    let level = case verbosity of
                   Debug  -> DEBUG
                   Normal -> INFO
                   Quiet  -> WARNING
    logger  <- getRootLogger
    handler <- streamHandler stdout DEBUG
    let handler' = setFormatter handler (tfLogFormatter "%Y-%m-%dT%H:%M:%SZ" "$time  $msg")
    let logger' = (setHandlers [handler'] . setLevel level) logger
    saveGlobalLogger logger'
    debugM "Program.initialize" "Logging initialized"
    quit <- newEmptyMVar
    _ <- installHandler sigINT  (interruptHandler quit) Nothing
    _ <- installHandler sigTERM (terminateHandler quit) Nothing
    _ <- installHandler sigQUIT quitHandler Nothing
    debugM "Program.initialize" "Signal handlers installed"
    return quit