module HMGit.Commands.Plumbing.HashObject.Core (
    HashObject (..)
  , hashObjectShow
  , hashObjectWrite
  , hashObject
) where

import           HMGit.Internal.Core        (ObjectInfo (..), fromContents,
                                             storeObject)
import           HMGit.Internal.Core.Runner (HMGitT)
import           HMGit.Internal.Parser      (ObjectType (..))
import           HMGit.Internal.Utils       (hexStr)

import           Control.Exception.Safe     (MonadCatch)
import           Control.Monad              ((>=>))
import           Control.Monad.IO.Class     (MonadIO (..))
import qualified Data.ByteString.Lazy       as BL
import qualified Data.ByteString.Lazy.UTF8  as BLU

newtype HashObject m = HashObject (ObjectType -> BL.ByteString -> HMGitT m ())

hashObjectShow :: (MonadCatch m, MonadIO m)
    => HashObject m
hashObjectShow :: HashObject m
hashObjectShow = (ObjectType -> ByteString -> HMGitT m ()) -> HashObject m
forall (m :: * -> *).
(ObjectType -> ByteString -> HMGitT m ()) -> HashObject m
HashObject ((ObjectType -> ByteString -> HMGitT m ()) -> HashObject m)
-> (ObjectType -> ByteString -> HMGitT m ()) -> HashObject m
forall a b. (a -> b) -> a -> b
$ \ObjectType
objType ->
    ObjectType -> ByteString -> HMGitT m ObjectInfo
forall (m :: * -> *).
MonadCatch m =>
ObjectType -> ByteString -> HMGitT m ObjectInfo
fromContents ObjectType
objType
        (ByteString -> HMGitT m ObjectInfo)
-> (ObjectInfo -> HMGitT m ()) -> ByteString -> HMGitT m ()
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> IO () -> HMGitT m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> HMGitT m ())
-> (ObjectInfo -> IO ()) -> ObjectInfo -> HMGitT m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO ()
putStrLn (String -> IO ()) -> (ObjectInfo -> String) -> ObjectInfo -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> String
forall mono.
(MonoFoldable mono, PrintfArg (Element mono)) =>
mono -> String
hexStr (ByteString -> String)
-> (ObjectInfo -> ByteString) -> ObjectInfo -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ObjectInfo -> ByteString
objectId

hashObjectWrite :: (MonadCatch m, MonadIO m)
    => HashObject m
hashObjectWrite :: HashObject m
hashObjectWrite = (ObjectType -> ByteString -> HMGitT m ()) -> HashObject m
forall (m :: * -> *).
(ObjectType -> ByteString -> HMGitT m ()) -> HashObject m
HashObject ((ObjectType -> ByteString -> HMGitT m ()) -> HashObject m)
-> (ObjectType -> ByteString -> HMGitT m ()) -> HashObject m
forall a b. (a -> b) -> a -> b
$ \ObjectType
objType ->
    ObjectType -> ByteString -> HMGitT m ByteString
forall (m :: * -> *).
(MonadIO m, MonadCatch m) =>
ObjectType -> ByteString -> HMGitT m ByteString
storeObject ObjectType
objType
        (ByteString -> HMGitT m ByteString)
-> (ByteString -> HMGitT m ()) -> ByteString -> HMGitT m ()
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> IO () -> HMGitT m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> HMGitT m ())
-> (ByteString -> IO ()) -> ByteString -> HMGitT m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO ()
putStrLn (String -> IO ()) -> (ByteString -> String) -> ByteString -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> String
forall mono.
(MonoFoldable mono, PrintfArg (Element mono)) =>
mono -> String
hexStr

hashObject :: (MonadCatch m, MonadIO m)
    => HashObject m
    -> ObjectType
    -> FilePath
    -> HMGitT m ()
hashObject :: HashObject m -> ObjectType -> String -> HMGitT m ()
hashObject (HashObject ObjectType -> ByteString -> HMGitT m ()
f) ObjectType
objType String
fpath =
    IO String -> ReaderT HMGitConfig m String
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (String -> IO String
readFile String
fpath)
        ReaderT HMGitConfig m String
-> (String -> HMGitT m ()) -> HMGitT m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ObjectType -> ByteString -> HMGitT m ()
f ObjectType
objType (ByteString -> HMGitT m ())
-> (String -> ByteString) -> String -> HMGitT m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ByteString
BLU.fromString