{-# LANGUAGE OverloadedStrings #-}
module Pirandello.Config ( ParseException, Config (..), Host, Port
                         , defaultPort, defaultConfig, decodeConfigFile, defaultConfigFile )
                         where

import Control.Applicative ((<$>), (<*>))
import Control.Monad (mzero)
import Control.Monad.Trans.Except (ExceptT (ExceptT))
import Data.Text (Text)
import Data.Word (Word16)
import Data.Yaml (FromJSON (parseJSON), ParseException, Value (Object), (.:?), (.!=), decodeFileEither)
import Pirandello.Events (RemoteId)
import System.Environment.XDG.BaseDir (getUserConfigFile)
import UnexceptionalIO (UIO, unsafeFromIO)

type Host = Text
type Port = Word16

data Config = Config { krugerServer ∷ Maybe Host
                     , krugerName ∷ Maybe RemoteId
                     , port ∷ Port }
                     deriving (Show, Eq)

instance FromJSON Config where
    parseJSON (Object v) = Config <$> v .:? "kruger-server"
                                  <*> v .:? "kruger-name"
                                  <*> v .:? "port" .!= defaultPort
    parseJSON _          = mzero

defaultPort ∷ Word16
defaultPort = 30716

defaultConfig ∷ Config
defaultConfig = Config Nothing Nothing defaultPort

decodeConfigFile ∷ FilePath → ExceptT ParseException UIO Config
decodeConfigFile = ExceptT . unsafeFromIO . decodeFileEither

defaultConfigFile ∷ UIO FilePath
defaultConfigFile = unsafeFromIO $ getUserConfigFile "pirandello" "config.yml"
