{-# LANGUAGE UnicodeSyntax #-}

-- | Module for parsing config files
module Todos.ReadConfig
  (readConfig)
  where

import Prelude hiding (putStrLn,readFile,getContents,print)
import Todos.IO
import System.Environment
import System.FilePath 
import System.Directory (doesFileExist)
import Text.ParserCombinators.Parsec

import Todos.Unicode

word  Parser String
word = choice $ map try [quotedOption, simpleOption, quoted, simpleWord]

simpleWord = many1 $ noneOf " \t\r\n=\"'"

quotedOption = (try quotedLongOption) <|> quotedShortOption

quotedLongOption  Parser String
quotedLongOption = do
  string "--"
  o  simpleWord
  char '='
  v  quoted
  return ("--"  o  "="  v)

quotedShortOption  Parser String
quotedShortOption = do
  string "-"
  o  simpleWord
  v  quoted
  return ("-"  o  v)

simpleOption = do
  o  simpleWord
  optional $ char '='
  v  simpleWord
  return (o  "="  v)

quoted = quoted1 <|> quoted2

quoted1 = do
  char '\''
  s  many1 $ noneOf "'"
  char '\''
  return s

quoted2 = do
  char '"'
  s  many1 $ noneOf "\""
  char '"'
  return s

pConfig  Parser [String]
pConfig = word `sepBy` space

parseConfig  String  [String]
parseConfig str = 
  case parse pConfig "config file" str of
    Right lst  lst
    Left err  error $ show err

readFile'  FilePath  IO [String]
readFile' path = 
  do b  doesFileExist path
     if not b
       then return []
       else do
              str  readFile path
              return $ parseConfig (unwords $ lines str)

-- | Read list of options from config files
readConfig  IO [String]
readConfig = do
  home  getEnv "HOME"
  let homepath = home </> ".config" </> "todos" </> "todos.conf"
  homecfg  readFile' homepath
  localcfg  readFile' ".todos.conf"
  return $ homecfg  localcfg