    --------------------------------------------------------------------------------
    module Hakyll.Core.Provider.MetadataCache
        ( resourceMetadata
        , resourceBody
        , resourceInvalidateMetadataCache
        ) where

    --------------------------------------------------------------------------------
    import           Control.Monad                 (unless)
    import           Hakyll.Core.Identifier
    import           Hakyll.Core.Metadata
    import           Hakyll.Core.Provider.Internal
    import           Hakyll.Core.Provider.Metadata
    import qualified Hakyll.Core.Store             as Store

    --------------------------------------------------------------------------------
    resourceMetadata :: Provider -> Identifier -> IO Metadata
    resourceMetadata :: Provider -> Identifier -> IO Metadata
    resourceMetadata p :: Provider
    p r :: Identifier
    r
        | Bool -> Bool
    not (Provider -> Identifier -> Bool
    resourceExists Provider
    p Identifier
    r) = Metadata -> IO Metadata
    forall (m :: * -> *) a. Monad m => a -> m a
    return Metadata
    forall a. Monoid a => a
    mempty
        | Bool
    otherwise                = do
            -- TODO keep time in md cache
            Provider -> Identifier -> IO ()
    load Provider
    p Identifier
    r
            Store.Found (BinaryMetadata md :: Metadata
    md) <- Store -> [String] -> IO (Result BinaryMetadata)
    forall a.
    (Binary a, Typeable a) =>
    Store -> [String] -> IO (Result a)
    Store.get (Provider -> Store
    providerStore Provider
    p)
                [String
    name, Identifier -> String
    toFilePath Identifier
    r, "metadata"]
            Metadata -> IO Metadata
    forall (m :: * -> *) a. Monad m => a -> m a
    return Metadata
    md

    --------------------------------------------------------------------------------
    resourceBody :: Provider -> Identifier -> IO String
    resourceBody :: Provider -> Identifier -> IO String
    resourceBody p :: Provider
    p r :: Identifier
    r = do
        Provider -> Identifier -> IO ()
    load Provider
    p Identifier
    r
        Store.Found bd :: Maybe String
    bd <- Store -> [String] -> IO (Result (Maybe String))
    forall a.
    (Binary a, Typeable a) =>
    Store -> [String] -> IO (Result a)
    Store.get (Provider -> Store
    providerStore Provider
    p)
            [String
    name, Identifier -> String
    toFilePath Identifier
    r, "body"]
        IO String -> (String -> IO String) -> Maybe String -> IO String
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (Provider -> Identifier -> IO String
    resourceString Provider
    p Identifier
    r) String -> IO String
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe String
    bd

    --------------------------------------------------------------------------------
    resourceInvalidateMetadataCache :: Provider -> Identifier -> IO ()
    resourceInvalidateMetadataCache :: Provider -> Identifier -> IO ()
    resourceInvalidateMetadataCache p :: Provider
    p r :: Identifier
    r = do
        Store -> [String] -> IO ()
    Store.delete (Provider -> Store
    providerStore Provider
    p) [String
    name, Identifier -> String
    toFilePath Identifier
    r, "metadata"]
        Store -> [String] -> IO ()
    Store.delete (Provider -> Store
    providerStore Provider
    p) [String
    name, Identifier -> String
    toFilePath Identifier
    r, "body"]

    --------------------------------------------------------------------------------
    load :: Provider -> Identifier -> IO ()
    load :: Provider -> Identifier -> IO ()
    load p :: Provider
    p r :: Identifier
    r = do
        Bool
    mmof <- Store -> [String] -> IO Bool
    Store.isMember Store
    store [String]
    mdk
        Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    unless Bool
    mmof (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ do
            (md :: Metadata
    md, body :: Maybe String
    body) <- Provider -> Identifier -> IO (Metadata, Maybe String)
    loadMetadata Provider
    p Identifier
    r
            Store -> [String] -> BinaryMetadata -> IO ()
    forall a. (Binary a, Typeable a) => Store -> [String] -> a -> IO ()
    Store.set Store
    store [String]
    mdk (Metadata -> BinaryMetadata
    BinaryMetadata Metadata
    md)
            Store -> [String] -> Maybe String -> IO ()
    forall a. (Binary a, Typeable a) => Store -> [String] -> a -> IO ()
    Store.set Store
    store [String]
    bk  Maybe String
    body
      where
        store :: Store
    store = Provider -> Store
    providerStore Provider
    p
        mdk :: [String]
    mdk   = [String
    name, Identifier -> String
    toFilePath Identifier
    r, "metadata"]
        bk :: [String]
    bk    = [String
    name, Identifier -> String
    toFilePath Identifier
    r, "body"]

    --------------------------------------------------------------------------------
    name :: String
    name :: String
    name = "Hakyll.Core.Resource.Provider.MetadataCache"