{-# LANGUAGE OverloadedStrings #-}

-- |
-- Module      :  Network.Ipfs.Api.Object
-- Copyright   :  Aleksandr Krupenkin 2016-2021
-- License     :  Apache-2.0
--
-- Maintainer  :  mail@akru.me
-- Stability   :  experimental
-- Portability :  unknown
--
-- Api calls with `object` prefix.
--

module Network.Ipfs.Api.Object where

import           Control.Monad.IO.Class         (MonadIO)
import           Data.Aeson                     (decode)
import           Data.Text                      (Text)
import           Network.HTTP.Client            (responseBody)

import           Network.Ipfs.Api.Internal      (_objectAddLink, _objectData,
                                                 _objectDiff, _objectGet,
                                                 _objectGetLinks, _objectNew,
                                                 _objectRmLink, _objectStat)
import           Network.Ipfs.Api.Internal.Call (call, multipartCall)
import           Network.Ipfs.Api.Types         (ObjectDiffObj, ObjectGetObj,
                                                 ObjectLinksObj, ObjectObj,
                                                 ObjectReturnType,
                                                 ObjectStatObj)
import           Network.Ipfs.Client            (IpfsT)

-- | Output the raw bytes of an IPFS object.
object :: MonadIO m => Text -> IpfsT m ObjectReturnType
object :: Text -> IpfsT m Text
object = ClientM Text -> IpfsT m Text
forall (m :: * -> *) a. MonadIO m => ClientM a -> IpfsT m a
call (ClientM Text -> IpfsT m Text)
-> (Text -> ClientM Text) -> Text -> IpfsT m Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ClientM Text
_objectData

-- | Create a new object from an ipfs template.
new :: MonadIO m => IpfsT m ObjectObj
new :: IpfsT m ObjectObj
new = ClientM ObjectObj -> IpfsT m ObjectObj
forall (m :: * -> *) a. MonadIO m => ClientM a -> IpfsT m a
call ClientM ObjectObj
_objectNew

-- | Output the links pointed to by the specified object.
getLinks :: MonadIO m => Text -> IpfsT m ObjectLinksObj
getLinks :: Text -> IpfsT m ObjectLinksObj
getLinks = ClientM ObjectLinksObj -> IpfsT m ObjectLinksObj
forall (m :: * -> *) a. MonadIO m => ClientM a -> IpfsT m a
call (ClientM ObjectLinksObj -> IpfsT m ObjectLinksObj)
-> (Text -> ClientM ObjectLinksObj)
-> Text
-> IpfsT m ObjectLinksObj
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ClientM ObjectLinksObj
_objectGetLinks

-- | Add a Merkle-link to the given object and return the hash of the result.
addLink :: MonadIO m => Text -> Text -> Text -> IpfsT m ObjectLinksObj
addLink :: Text -> Text -> Text -> IpfsT m ObjectLinksObj
addLink Text
hash Text
name = ClientM ObjectLinksObj -> IpfsT m ObjectLinksObj
forall (m :: * -> *) a. MonadIO m => ClientM a -> IpfsT m a
call (ClientM ObjectLinksObj -> IpfsT m ObjectLinksObj)
-> (Text -> ClientM ObjectLinksObj)
-> Text
-> IpfsT m ObjectLinksObj
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe Text -> Maybe Text -> ClientM ObjectLinksObj
_objectAddLink Text
hash (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
name) (Maybe Text -> ClientM ObjectLinksObj)
-> (Text -> Maybe Text) -> Text -> ClientM ObjectLinksObj
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe Text
forall a. a -> Maybe a
Just

-- | Remove a Merkle-link from the given object and return the hash of the result.
rmLink :: MonadIO m => Text -> Text -> IpfsT m ObjectLinksObj
rmLink :: Text -> Text -> IpfsT m ObjectLinksObj
rmLink Text
key = ClientM ObjectLinksObj -> IpfsT m ObjectLinksObj
forall (m :: * -> *) a. MonadIO m => ClientM a -> IpfsT m a
call (ClientM ObjectLinksObj -> IpfsT m ObjectLinksObj)
-> (Text -> ClientM ObjectLinksObj)
-> Text
-> IpfsT m ObjectLinksObj
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe Text -> ClientM ObjectLinksObj
_objectRmLink Text
key (Maybe Text -> ClientM ObjectLinksObj)
-> (Text -> Maybe Text) -> Text -> ClientM ObjectLinksObj
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe Text
forall a. a -> Maybe a
Just

-- | Append data to what already exists in the data segment in the given object.
appendData :: MonadIO m => Text -> Text -> IpfsT m (Maybe ObjectLinksObj)
appendData :: Text -> Text -> IpfsT m (Maybe ObjectLinksObj)
appendData Text
key = (Response ByteString -> Maybe ObjectLinksObj)
-> IpfsT m (Response ByteString) -> IpfsT m (Maybe ObjectLinksObj)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Response ByteString -> Maybe ObjectLinksObj
decodeResponse (IpfsT m (Response ByteString) -> IpfsT m (Maybe ObjectLinksObj))
-> (Text -> IpfsT m (Response ByteString))
-> Text
-> IpfsT m (Maybe ObjectLinksObj)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text -> IpfsT m (Response ByteString)
forall (m :: * -> *).
MonadIO m =>
Text -> Text -> IpfsT m (Response ByteString)
multipartCall (Text
"object/patch/append-data?arg=" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
key)
  where
    decodeResponse :: Response ByteString -> Maybe ObjectLinksObj
decodeResponse = ByteString -> Maybe ObjectLinksObj
forall a. FromJSON a => ByteString -> Maybe a
decode (ByteString -> Maybe ObjectLinksObj)
-> (Response ByteString -> ByteString)
-> Response ByteString
-> Maybe ObjectLinksObj
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Response ByteString -> ByteString
forall body. Response body -> body
responseBody

-- | Set the data field of an IPFS object.
setData :: MonadIO m => Text -> Text -> IpfsT m (Maybe ObjectLinksObj)
setData :: Text -> Text -> IpfsT m (Maybe ObjectLinksObj)
setData Text
key = (Response ByteString -> Maybe ObjectLinksObj)
-> IpfsT m (Response ByteString) -> IpfsT m (Maybe ObjectLinksObj)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Response ByteString -> Maybe ObjectLinksObj
decodeResponse (IpfsT m (Response ByteString) -> IpfsT m (Maybe ObjectLinksObj))
-> (Text -> IpfsT m (Response ByteString))
-> Text
-> IpfsT m (Maybe ObjectLinksObj)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text -> IpfsT m (Response ByteString)
forall (m :: * -> *).
MonadIO m =>
Text -> Text -> IpfsT m (Response ByteString)
multipartCall (Text
"object/patch/set-data?arg=" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
key)
  where
    decodeResponse :: Response ByteString -> Maybe ObjectLinksObj
decodeResponse = ByteString -> Maybe ObjectLinksObj
forall a. FromJSON a => ByteString -> Maybe a
decode (ByteString -> Maybe ObjectLinksObj)
-> (Response ByteString -> ByteString)
-> Response ByteString
-> Maybe ObjectLinksObj
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Response ByteString -> ByteString
forall body. Response body -> body
responseBody

-- | Get and serialize the DAG node named by key.
get :: MonadIO m => Text -> IpfsT m ObjectGetObj
get :: Text -> IpfsT m ObjectGetObj
get = ClientM ObjectGetObj -> IpfsT m ObjectGetObj
forall (m :: * -> *) a. MonadIO m => ClientM a -> IpfsT m a
call (ClientM ObjectGetObj -> IpfsT m ObjectGetObj)
-> (Text -> ClientM ObjectGetObj) -> Text -> IpfsT m ObjectGetObj
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ClientM ObjectGetObj
_objectGet

-- | 'Display the diff between two ipfs objects.
diff :: MonadIO m => Text -> Text -> IpfsT m ObjectDiffObj
diff :: Text -> Text -> IpfsT m ObjectDiffObj
diff Text
firstKey = ClientM ObjectDiffObj -> IpfsT m ObjectDiffObj
forall (m :: * -> *) a. MonadIO m => ClientM a -> IpfsT m a
call (ClientM ObjectDiffObj -> IpfsT m ObjectDiffObj)
-> (Text -> ClientM ObjectDiffObj) -> Text -> IpfsT m ObjectDiffObj
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe Text -> ClientM ObjectDiffObj
_objectDiff Text
firstKey (Maybe Text -> ClientM ObjectDiffObj)
-> (Text -> Maybe Text) -> Text -> ClientM ObjectDiffObj
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe Text
forall a. a -> Maybe a
Just

-- | Store input as a DAG object, print its key.
put :: MonadIO m => Text -> IpfsT m (Maybe ObjectObj)
put :: Text -> IpfsT m (Maybe ObjectObj)
put = (Response ByteString -> Maybe ObjectObj)
-> IpfsT m (Response ByteString) -> IpfsT m (Maybe ObjectObj)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Response ByteString -> Maybe ObjectObj
decodeResponse (IpfsT m (Response ByteString) -> IpfsT m (Maybe ObjectObj))
-> (Text -> IpfsT m (Response ByteString))
-> Text
-> IpfsT m (Maybe ObjectObj)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text -> IpfsT m (Response ByteString)
forall (m :: * -> *).
MonadIO m =>
Text -> Text -> IpfsT m (Response ByteString)
multipartCall Text
"object/put"
  where
    decodeResponse :: Response ByteString -> Maybe ObjectObj
decodeResponse = ByteString -> Maybe ObjectObj
forall a. FromJSON a => ByteString -> Maybe a
decode (ByteString -> Maybe ObjectObj)
-> (Response ByteString -> ByteString)
-> Response ByteString
-> Maybe ObjectObj
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Response ByteString -> ByteString
forall body. Response body -> body
responseBody

-- | Get stats for the DAG node named by key.
objectStat :: MonadIO m => Text -> IpfsT m ObjectStatObj
objectStat :: Text -> IpfsT m ObjectStatObj
objectStat = ClientM ObjectStatObj -> IpfsT m ObjectStatObj
forall (m :: * -> *) a. MonadIO m => ClientM a -> IpfsT m a
call (ClientM ObjectStatObj -> IpfsT m ObjectStatObj)
-> (Text -> ClientM ObjectStatObj) -> Text -> IpfsT m ObjectStatObj
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ClientM ObjectStatObj
_objectStat