{-|This module provides a convenient way to decode a 'Manager' from json string

Note: You are recommend to use "Logging.Config.Yaml", because of yaml is easier
to read and write.

=== Template
@
  {
    \"sinks\":
    {
      \"root\":
      {
        \"handlers\": [\"console\", \"file\"]
      },
      \"App.Json\":
      {
        \"handlers\": [\"file\"],
        \"propagate\": false
      },
      \"App.Yaml\":
      {
        \"handlers\": [\"rotate\"],
        \"propagate\": false
      }
    },
    \"handlers\":
    {
      \"console\":
      {
        \"type\": \"StreamHandler\",
        \"level\": \"DEBUG\",
        \"formatter\": \"simple\",
        \"stream\": \"stderr\"
      },
      \"file\":
      {
        \"type\": \"FileHandler\",
        \"level\": \"Level 100\",
        \"filterer\": [\"App.Json\"],
        \"formatter\": \"standard\",
        \"file\": \"\/var\/log\/my\/json.log",
        \"encoding\": \"utf8\"
      },
      \"rotate\":
      {
        \"type\": \"RotatingFileHandler\",
        \"level\": \"INFO\",
        \"filterer\": [\"App.Yaml\"],
        \"formatter\": \"standard\",
        \"file\": \"\/var\/log\/my\/json.log",
        \"encoding\": \"utf8\",
        \"maxBytes\": 1048576,
        \"backupCount\": 10
      }
    },
    \"formatters\":
    {
      \"simple\": \"{message}\",
      \"standard\": \"{asctime:%Y-%m-%dT%H:%M:%S%6Q%z} - {level} - {logger}] {message}\"
    },
    \"disabled\": false
  }
@
-}
module Logging.Config.Json (getManager, getManagerFile) where


import           Control.Exception
import           Data.Aeson
import           Data.ByteString
import           Prelude             hiding (readFile)

import           Logging.Config.Type
import           Logging.Manager


-- | decode a 'Manager' from strict 'ByteString', it
-- 1) decodes 'Config' from json string, 2) constructs an 'Manager'
--
-- @since 0.4.0
getManager :: ByteString -> IO Manager
getManager bs =
  case eitherDecodeStrict bs of
    Left msg     -> throw $ ConfigException msg
    Right config -> createManager config


-- | decode a 'Manager' from a file, it
-- 1) reads json string from file, 2) calls getManager to construct an 'Manager'
--
-- @since 0.4.0
getManagerFile :: FilePath -> IO Manager
getManagerFile path = getManager =<< catch (readFile path) reThrow
  where
    reThrow :: SomeException -> IO a
    reThrow e = throw $ ConfigException $ displayException e