{- |
Module      : RsiBreak.Actions
Copyright   : (c) Ruben Astudillo, 2023
License     : BSD-2
Maintainer  : ruben.astud@gmail.com

Actions to be run on change of values such as settings.
-}

module RsiBreak.Actions (getOrCreateConfigFile, storeSettingsOnConfigFile) where

import Control.Monad (unless)
import Data.Ini.Config.Bidir
import Data.Text.IO qualified as TIO (readFile, writeFile)
import RsiBreak.Model.Settings
import System.Directory
import System.FilePath ((</>))

getOrCreateConfigFile :: IO TimerSetting
getOrCreateConfigFile :: IO TimerSetting
getOrCreateConfigFile = do
    FilePath
dir <- XdgDirectory -> FilePath -> IO FilePath
getXdgDirectory XdgDirectory
XdgConfig FilePath
"rsi-break"
    let file :: FilePath
file = FilePath
dir FilePath -> FilePath -> FilePath
</> FilePath
"settings.ini"
    Bool
settingsFileExist <- FilePath -> IO Bool
doesFileExist FilePath
file
    Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
settingsFileExist (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
        FilePath -> FilePath -> IO ()
createNewInitialSettings FilePath
dir FilePath
file
    Text
settingFileContent <- FilePath -> IO Text
TIO.readFile FilePath
file
    let eIniSettings :: Either FilePath (Ini TimerSetting)
eIniSettings = Text -> Ini TimerSetting -> Either FilePath (Ini TimerSetting)
forall s. Text -> Ini s -> Either FilePath (Ini s)
parseIni Text
settingFileContent Ini TimerSetting
defaultIni
    case Either FilePath (Ini TimerSetting)
eIniSettings of
        Left FilePath
_err -> do
            FilePath -> IO ()
removeDirectoryRecursive FilePath
dir
            FilePath -> FilePath -> IO ()
createNewInitialSettings FilePath
dir FilePath
file
            TimerSetting -> IO TimerSetting
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure TimerSetting
defSetting
        Right Ini TimerSetting
ini' -> TimerSetting -> IO TimerSetting
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Ini TimerSetting -> TimerSetting
forall s. Ini s -> s
getIniValue Ini TimerSetting
ini')
  where
    createNewInitialSettings :: FilePath -> FilePath -> IO ()
createNewInitialSettings FilePath
dir FilePath
file = do
        FilePath -> IO ()
createDirectory FilePath
dir
        FilePath -> Text -> IO ()
TIO.writeFile FilePath
file (Ini TimerSetting -> Text
forall s. Ini s -> Text
serializeIni Ini TimerSetting
defaultIni)

defaultIni :: Ini TimerSetting
defaultIni :: Ini TimerSetting
defaultIni =
    UpdatePolicy -> Ini TimerSetting -> Ini TimerSetting
forall s. UpdatePolicy -> Ini s -> Ini s
setIniUpdatePolicy
        (UpdatePolicy
defaultUpdatePolicy{updateGeneratedCommentPolicy :: UpdateCommentPolicy
updateGeneratedCommentPolicy = UpdateCommentPolicy
CommentPolicyAddFieldComment})
        (TimerSetting -> IniSpec TimerSetting () -> Ini TimerSetting
forall s. s -> IniSpec s () -> Ini s
ini TimerSetting
defSetting IniSpec TimerSetting ()
timerSettingSpec)

storeSettingsOnConfigFile :: TimerSetting -> IO ()
storeSettingsOnConfigFile :: TimerSetting -> IO ()
storeSettingsOnConfigFile TimerSetting
updatedSettings = do
    let updatedIni :: Ini TimerSetting
updatedIni = TimerSetting -> Ini TimerSetting -> Ini TimerSetting
forall s. s -> Ini s -> Ini s
updateIni TimerSetting
updatedSettings Ini TimerSetting
defaultIni
    FilePath
dir <- XdgDirectory -> FilePath -> IO FilePath
getXdgDirectory XdgDirectory
XdgConfig FilePath
"rsi-break"
    let file :: FilePath
file = FilePath
dir FilePath -> FilePath -> FilePath
</> FilePath
"settings.ini"
    FilePath -> Text -> IO ()
TIO.writeFile FilePath
file (Ini TimerSetting -> Text
forall s. Ini s -> Text
serializeIni Ini TimerSetting
updatedIni)