{-# LANGUAGE FlexibleContexts #-}

module Package.C.Db.Memory ( strictIndex
                           , pkgIndex
                           , globalPkgDir
                           , memIndex
                           ) where

import           Control.Monad.State.Class
import           CPkgPrelude
import           Data.Binary               (decode)
import qualified Data.ByteString           as BS
import qualified Data.ByteString.Lazy      as BSL
import           Package.C.Db.Monad
import           Package.C.Db.Type

pkgIndex :: MonadIO m => m FilePath
pkgIndex :: forall (m :: * -> *). MonadIO m => m FilePath
pkgIndex = (FilePath -> FilePath -> FilePath
</> FilePath
"index.bin") (FilePath -> FilePath) -> m FilePath -> m FilePath
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m FilePath
forall (m :: * -> *). MonadIO m => m FilePath
globalPkgDir

globalPkgDir :: MonadIO m => m FilePath
globalPkgDir :: forall (m :: * -> *). MonadIO m => m FilePath
globalPkgDir = IO FilePath -> m FilePath
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (FilePath -> IO FilePath
getAppUserDataDirectory FilePath
"cpkg")

memIndex :: MonadDb m => m InstallDb
memIndex :: forall (m :: * -> *). MonadDb m => m InstallDb
memIndex = m InstallDb
forall s (m :: * -> *). MonadState s m => m s
get

strictIndex :: MonadIO m => m InstallDb
strictIndex :: forall (m :: * -> *). MonadIO m => m InstallDb
strictIndex = do

    FilePath
indexFile <- m FilePath
forall (m :: * -> *). MonadIO m => m FilePath
pkgIndex
    -- Add some proper error handling here
    Bool
existsIndex <- IO Bool -> m Bool
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (FilePath -> IO Bool
doesFileExist FilePath
indexFile)

    if Bool
existsIndex
        then ByteString -> InstallDb
forall a. Binary a => ByteString -> a
decode (ByteString -> InstallDb)
-> (ByteString -> ByteString) -> ByteString -> InstallDb
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
BSL.fromStrict (ByteString -> InstallDb) -> m ByteString -> m InstallDb
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO ByteString -> m ByteString
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (FilePath -> IO ByteString
BS.readFile FilePath
indexFile)
        else InstallDb -> m InstallDb
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure InstallDb
forall a. Monoid a => a
mempty