{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}

module Simplex.Chat.Store.AppSettings where

import Control.Monad (join)
import Control.Monad.IO.Class (liftIO)
import Data.Maybe (fromMaybe)
import Simplex.Chat.AppSettings (AppSettings (..), combineAppSettings, defaultAppSettings, defaultParseAppSettings)
import Simplex.Messaging.Agent.Store.AgentStore (maybeFirstRow)
import qualified Simplex.Messaging.Agent.Store.DB as DB
import Simplex.Messaging.Util (decodeJSON, encodeJSON)

#if defined(dbPostgres)
import Database.PostgreSQL.Simple (Only (..))
#else
import Database.SQLite.Simple (Only (..))
#endif

saveAppSettings :: DB.Connection -> AppSettings -> IO ()
saveAppSettings :: Connection -> AppSettings -> IO ()
saveAppSettings Connection
db AppSettings
appSettings = do
  Connection -> Query -> IO ()
DB.execute_ Connection
db Query
"DELETE FROM app_settings"
  Connection -> Query -> Only Text -> IO ()
forall q. ToRow q => Connection -> Query -> q -> IO ()
DB.execute Connection
db Query
"INSERT INTO app_settings (app_settings) VALUES (?)" (Text -> Only Text
forall a. a -> Only a
Only (Text -> Only Text) -> Text -> Only Text
forall a b. (a -> b) -> a -> b
$ AppSettings -> Text
forall a. ToJSON a => a -> Text
encodeJSON AppSettings
appSettings)

getAppSettings :: DB.Connection -> Maybe AppSettings -> IO AppSettings
getAppSettings :: Connection -> Maybe AppSettings -> IO AppSettings
getAppSettings Connection
db Maybe AppSettings
platformDefaults = do
  Maybe AppSettings
stored_ <- Maybe (Maybe AppSettings) -> Maybe AppSettings
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (Maybe (Maybe AppSettings) -> Maybe AppSettings)
-> IO (Maybe (Maybe AppSettings)) -> IO (Maybe AppSettings)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO (Maybe (Maybe AppSettings)) -> IO (Maybe (Maybe AppSettings))
forall a. IO a -> IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO ((Only Text -> Maybe AppSettings)
-> IO [Only Text] -> IO (Maybe (Maybe AppSettings))
forall (f :: * -> *) a b.
Functor f =>
(a -> b) -> f [a] -> f (Maybe b)
maybeFirstRow (Text -> Maybe AppSettings
forall a. FromJSON a => Text -> Maybe a
decodeJSON (Text -> Maybe AppSettings)
-> (Only Text -> Text) -> Only Text -> Maybe AppSettings
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Only Text -> Text
forall a. Only a -> a
fromOnly) (IO [Only Text] -> IO (Maybe (Maybe AppSettings)))
-> IO [Only Text] -> IO (Maybe (Maybe AppSettings))
forall a b. (a -> b) -> a -> b
$ Connection -> Query -> IO [Only Text]
forall r. FromRow r => Connection -> Query -> IO [r]
DB.query_ Connection
db Query
"SELECT app_settings FROM app_settings")
  AppSettings -> IO AppSettings
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AppSettings -> IO AppSettings) -> AppSettings -> IO AppSettings
forall a b. (a -> b) -> a -> b
$ AppSettings -> AppSettings -> AppSettings
combineAppSettings (AppSettings -> Maybe AppSettings -> AppSettings
forall a. a -> Maybe a -> a
fromMaybe AppSettings
defaultAppSettings Maybe AppSettings
platformDefaults) (AppSettings -> Maybe AppSettings -> AppSettings
forall a. a -> Maybe a -> a
fromMaybe AppSettings
defaultParseAppSettings Maybe AppSettings
stored_)