module Termonad.PreferencesFile where

import Termonad.Prelude

import Data.Yaml (decodeFileEither, encode, prettyPrintParseException)
import System.Directory
  ( XdgDirectory(XdgConfig)
  , createDirectoryIfMissing
  , doesFileExist
  , getXdgDirectory
  )

import Termonad.Types
  ( ConfigOptions
  , TMConfig(TMConfig, hooks, options)
  , defaultConfigHooks
  , defaultConfigOptions
  )

-- | Get the path to the preferences file @~\/.config\/termonad\/termonad.yaml@.
getPreferencesFile :: IO FilePath
getPreferencesFile = do
  -- Get the termonad config directory
  confDir <- getXdgDirectory XdgConfig "termonad"
  createDirectoryIfMissing True confDir
  pure $ confDir </> "termonad.yaml"

-- | Read the configuration for the preferences file
-- @~\/.config\/termonad\/termonad.yaml@. This file stores only the 'options' of
-- 'TMConfig' so 'hooks' are initialized with 'defaultConfigHooks'.  If the
-- file doesn't exist, create it with the default values.
tmConfigFromPreferencesFile :: IO TMConfig
tmConfigFromPreferencesFile = do
  confFile <- getPreferencesFile
  -- If there is no preferences file we create it with the default values
  exists <- doesFileExist confFile
  unless exists $ writePreferencesFile confFile defaultConfigOptions
  -- Read the configuration file
  eitherOptions <- decodeFileEither confFile
  options <-
    case eitherOptions of
      Left err -> do
        hPutStrLn stderr $ "Error parsing file " <> pack confFile
        hPutStrLn stderr $ pack $ prettyPrintParseException err
        pure defaultConfigOptions
      Right options -> pure options
  pure $ TMConfig { options = options, hooks = defaultConfigHooks }

writePreferencesFile :: FilePath -> ConfigOptions -> IO ()
writePreferencesFile confFile options = do
  let yaml = encode options
      yamlWithComment =
        "# DO NOT EDIT THIS FILE BY HAND!\n" <>
        "#\n" <>
        "# This file is generated automatically by the Preferences dialog\n" <>
        "# in Termonad.  Please open the Preferences dialog if you wish to\n" <>
        "# modify this file.\n" <>
        "#\n" <>
        "# The settings in this file will be ignored if you have a\n" <>
        "# termonad.hs file in this same directory.\n\n" <>
        yaml
  writeFile confFile yamlWithComment

-- | Save the configuration to the preferences file
-- @~\/.config\/termonad\/termonad.yaml@
saveToPreferencesFile :: TMConfig -> IO ()
saveToPreferencesFile TMConfig { options = options } = do
  confFile <- getPreferencesFile
  writePreferencesFile confFile options