module HashAddressed.App.Meta.Initialization
  (
    defaultConfigINI, tryInitializeStore, initializeStore,
    InitializationType (..),
  )
  where

import Essentials
import HashAddressed.App.HashFunction.Naming
import HashAddressed.App.Meta.Paths
import HashAddressed.App.Verbosity.Printing
import HashAddressed.App.Verbosity.Type
import HashAddressed.App.Command.Type

import Control.Monad.IO.Class (liftIO)
import Prelude (FilePath)

import qualified Data.ByteString as Strict.ByteString
import qualified Data.Ini as INI
import qualified Data.Text as Strict.Text
import qualified Data.Text.Encoding as Strict.Text
import qualified System.Directory as Directory

defaultConfigINI :: HashFunctionName -> INI.Ini
defaultConfigINI :: HashFunctionName -> Ini
defaultConfigINI HashFunctionName
optHashFunction = HashMap Text [(Text, Text)] -> [(Text, Text)] -> Ini
INI.Ini forall a. Monoid a => a
mempty
    [ (String -> Text
Strict.Text.pack String
"version", String -> Text
Strict.Text.pack String
"1")
    , (String -> Text
Strict.Text.pack String
"hash function",
      String -> Text
Strict.Text.pack (HashFunctionName -> String
showHashFunction HashFunctionName
optHashFunction))]

tryInitializeStore :: InitializationType -> Verbosity -> HashFunctionName -> FilePath -> CommandAction ()
tryInitializeStore :: InitializationType
-> Verbosity -> HashFunctionName -> String -> CommandAction ()
tryInitializeStore InitializationType
initializationType Verbosity
optVerbosity HashFunctionName
optHashFunction String
optStoreDirectory = do
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (String -> IO Bool
Directory.doesPathExist (String -> String
metaDirectory String
optStoreDirectory)) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Bool
False -> HashFunctionName -> String -> CommandAction ()
initializeStore HashFunctionName
optHashFunction String
optStoreDirectory
        Bool
True -> case InitializationType
initializationType of
            InitializationType
CreateNew -> HashFunctionName -> String -> CommandAction ()
initializeStore HashFunctionName
optHashFunction String
optStoreDirectory
            InitializationType
CreateIfNotPresent ->
                forall (m :: * -> *). MonadIO m => Verbosity -> String -> m ()
putVerboseLn Verbosity
optVerbosity String
"Store is already initialized."

data InitializationType = CreateNew | CreateIfNotPresent

{-| Assumes a store does not already exist -}
initializeStore :: HashFunctionName -> FilePath -> CommandAction ()
initializeStore :: HashFunctionName -> String -> CommandAction ()
initializeStore HashFunctionName
optHashFunction String
optStoreDirectory = do
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ Bool -> String -> IO ()
Directory.createDirectoryIfMissing Bool
True (String -> String
metaDirectory String
optStoreDirectory)
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ String -> ByteString -> IO ()
Strict.ByteString.writeFile (String -> String
configFile String
optStoreDirectory) forall a b. (a -> b) -> a -> b
$
        Text -> ByteString
Strict.Text.encodeUtf8 (Ini -> Text
INI.printIni (HashFunctionName -> Ini
defaultConfigINI HashFunctionName
optHashFunction))