module Network.IPFS.DAG
  ( put
  , putNode
  , putRemote
  ) where

import           Data.ByteString.Lazy.Char8        as CL
import qualified Network.IPFS.Internal.UTF8        as UTF8
import qualified RIO.ByteString.Lazy               as Lazy

import           Servant.Client
import qualified Servant.Multipart.Client          as Multipart.Client

import           Network.IPFS.Prelude

import           Network.IPFS.Add.Error            as IPFS.Add
import qualified Network.IPFS.Client               as IPFS.Client
import           Network.IPFS.Client.DAG.Put.Types as DAG.Put
import           Network.IPFS.DAG.Node.Types       as DAG
import           Network.IPFS.File.Form.Types      as File
import           Network.IPFS.File.Types           as File
import           Network.IPFS.Local.Class          as IPFS
import           Network.IPFS.Remote.Class         as IPFS
import           Network.IPFS.Types                as IPFS

put :: MonadLocalIPFS m => Lazy.ByteString -> m (Either IPFS.Add.Error IPFS.CID)
put :: forall (m :: * -> *).
MonadLocalIPFS m =>
ByteString -> m (Either Error CID)
put ByteString
raw = forall (m :: * -> *).
MonadLocalIPFS m =>
[Opt] -> ByteString -> m (Either Error ByteString)
IPFS.runLocal [Opt
"dag", Opt
"put", Opt
"-f", Opt
"dag-pb"] ByteString
raw forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
  Right ByteString
result ->
    case ByteString -> [ByteString]
CL.lines ByteString
result of
      [Item [ByteString]
cid] ->
        Item [ByteString]
cid
          forall a b. a -> (a -> b) -> b
|> forall a. Show a => a -> Text
UTF8.textShow
          forall a b. a -> (a -> b) -> b
|> Natural -> Text -> Text
UTF8.stripN Natural
1
          forall a b. a -> (a -> b) -> b
|> Text -> CID
mkCID
          forall a b. a -> (a -> b) -> b
|> forall a b. b -> Either a b
Right
          forall a b. a -> (a -> b) -> b
|> forall (m :: * -> *) a. Monad m => a -> m a
return

      [ByteString]
bad ->
        forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> Either a b
Left forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Error
UnexpectedOutput forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> Text
UTF8.textShow [ByteString]
bad

  Left Error
err ->
    forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> Either a b
Left forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Error
UnknownAddErr forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> Text
UTF8.textShow Error
err

putNode :: MonadLocalIPFS m => DAG.Node -> m (Either IPFS.Add.Error IPFS.CID)
putNode :: forall (m :: * -> *).
MonadLocalIPFS m =>
Node -> m (Either Error CID)
putNode Node
node = forall (m :: * -> *).
MonadLocalIPFS m =>
ByteString -> m (Either Error CID)
put forall a b. (a -> b) -> a -> b
$ forall a. ToJSON a => a -> ByteString
encode Node
node

putRemote :: MonadRemoteIPFS m => File.Serialized -> m (Either ClientError DAG.Put.Response)
putRemote :: forall (m :: * -> *).
MonadRemoteIPFS m =>
Serialized -> m (Either ClientError Response)
putRemote Serialized
file = do
  ByteString
boundary  <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO ByteString
Multipart.Client.genBoundary
  forall (m :: * -> *) a.
MonadRemoteIPFS m =>
ClientM a -> m (Either ClientError a)
runRemote (Bool -> (ByteString, Form) -> ClientM Response
IPFS.Client.dagPut Bool
True (ByteString
boundary, Text -> Serialized -> Form
File.Form Text
"file" Serialized
file))