{-# LANGUAGE NoImplicitPrelude #-}

module Stack.Types.FileDigestCache
  ( FileDigestCache
  , newFileDigestCache
  , readFileDigest
  ) where

import qualified Data.Map.Strict as Map
import           Stack.Prelude
import qualified Pantry.SHA256 as SHA256

-- | Type synonym representing caches of digests of files.

type FileDigestCache = IORef (Map FilePath SHA256)

newFileDigestCache :: MonadIO m => m FileDigestCache
newFileDigestCache :: forall (m :: * -> *). MonadIO m => m FileDigestCache
newFileDigestCache = Map FilePath SHA256 -> m FileDigestCache
forall (m :: * -> *) a. MonadIO m => a -> m (IORef a)
newIORef Map FilePath SHA256
forall k a. Map k a
Map.empty

readFileDigest :: MonadIO m => FileDigestCache -> FilePath -> m SHA256
readFileDigest :: forall (m :: * -> *).
MonadIO m =>
FileDigestCache -> FilePath -> m SHA256
readFileDigest FileDigestCache
cache FilePath
filePath = do
  Map FilePath SHA256
digests <- FileDigestCache -> m (Map FilePath SHA256)
forall (m :: * -> *) a. MonadIO m => IORef a -> m a
readIORef FileDigestCache
cache
  case FilePath -> Map FilePath SHA256 -> Maybe SHA256
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup FilePath
filePath Map FilePath SHA256
digests of
    Just SHA256
digest -> SHA256 -> m SHA256
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure SHA256
digest
    Maybe SHA256
Nothing -> do
      SHA256
sha256 <- FilePath -> m SHA256
forall (m :: * -> *). MonadIO m => FilePath -> m SHA256
SHA256.hashFile FilePath
filePath
      FileDigestCache -> Map FilePath SHA256 -> m ()
forall (m :: * -> *) a. MonadIO m => IORef a -> a -> m ()
writeIORef FileDigestCache
cache (Map FilePath SHA256 -> m ()) -> Map FilePath SHA256 -> m ()
forall a b. (a -> b) -> a -> b
$ FilePath -> SHA256 -> Map FilePath SHA256 -> Map FilePath SHA256
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert FilePath
filePath SHA256
sha256 Map FilePath SHA256
digests
      SHA256 -> m SHA256
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure SHA256
sha256