{-# LANGUAGE OverloadedStrings #-}

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

module Network.Ipfs.Api.Files where

import           Control.Monad.IO.Class         (MonadIO)
import           Data.Text                      (Text, pack)
import           Network.HTTP.Client            (responseStatus)
import           Network.HTTP.Types             (Status (..))
import           Servant.API.ContentTypes       (NoContent)

import           Network.Ipfs.Api.Internal      (_filesChcid, _filesCp,
                                                 _filesFlush, _filesLs,
                                                 _filesMkdir, _filesMv,
                                                 _filesRead, _filesRm,
                                                 _filesStat)
import           Network.Ipfs.Api.Internal.Call (call, multipartCall)
import           Network.Ipfs.Api.Types         (FilesFlushObj, FilesLsObj,
                                                 FilesReadType, FilesStatObj)
import           Network.Ipfs.Client            (IpfsT)

-- | Change the cid version or hash function of the root node of a given mfsPath.
chcidVer :: MonadIO m => Text -> Int -> IpfsT m NoContent
chcidVer :: Text -> Int -> IpfsT m NoContent
chcidVer Text
mfsPath = ClientM NoContent -> IpfsT m NoContent
forall (m :: * -> *) a. MonadIO m => ClientM a -> IpfsT m a
call (ClientM NoContent -> IpfsT m NoContent)
-> (Int -> ClientM NoContent) -> Int -> IpfsT m NoContent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe Text -> Maybe Int -> ClientM NoContent
_filesChcid (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
mfsPath) (Maybe Int -> ClientM NoContent)
-> (Int -> Maybe Int) -> Int -> ClientM NoContent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Maybe Int
forall a. a -> Maybe a
Just

-- | Copy files into mfs.
cp :: MonadIO m => Text -> Text -> IpfsT m NoContent
cp :: Text -> Text -> IpfsT m NoContent
cp Text
src = ClientM NoContent -> IpfsT m NoContent
forall (m :: * -> *) a. MonadIO m => ClientM a -> IpfsT m a
call (ClientM NoContent -> IpfsT m NoContent)
-> (Text -> ClientM NoContent) -> Text -> IpfsT m NoContent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe Text -> Maybe Text -> ClientM NoContent
_filesCp (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
src) (Maybe Text -> ClientM NoContent)
-> (Text -> Maybe Text) -> Text -> ClientM NoContent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe Text
forall a. a -> Maybe a
Just

-- | Flush a given path's data to disk.
flush :: MonadIO m => Text -> IpfsT m FilesFlushObj
flush :: Text -> IpfsT m FilesFlushObj
flush = ClientM FilesFlushObj -> IpfsT m FilesFlushObj
forall (m :: * -> *) a. MonadIO m => ClientM a -> IpfsT m a
call (ClientM FilesFlushObj -> IpfsT m FilesFlushObj)
-> (Text -> ClientM FilesFlushObj) -> Text -> IpfsT m FilesFlushObj
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe Text -> ClientM FilesFlushObj
_filesFlush (Maybe Text -> ClientM FilesFlushObj)
-> (Text -> Maybe Text) -> Text -> ClientM FilesFlushObj
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe Text
forall a. a -> Maybe a
Just

-- | List directories in the local mutable namespace.
ls :: MonadIO m => Text -> IpfsT m FilesLsObj
ls :: Text -> IpfsT m FilesLsObj
ls = ClientM FilesLsObj -> IpfsT m FilesLsObj
forall (m :: * -> *) a. MonadIO m => ClientM a -> IpfsT m a
call (ClientM FilesLsObj -> IpfsT m FilesLsObj)
-> (Text -> ClientM FilesLsObj) -> Text -> IpfsT m FilesLsObj
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe Text -> ClientM FilesLsObj
_filesLs (Maybe Text -> ClientM FilesLsObj)
-> (Text -> Maybe Text) -> Text -> ClientM FilesLsObj
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe Text
forall a. a -> Maybe a
Just

-- | Make directories.
mkdir :: MonadIO m => Text -> IpfsT m NoContent
mkdir :: Text -> IpfsT m NoContent
mkdir = ClientM NoContent -> IpfsT m NoContent
forall (m :: * -> *) a. MonadIO m => ClientM a -> IpfsT m a
call (ClientM NoContent -> IpfsT m NoContent)
-> (Text -> ClientM NoContent) -> Text -> IpfsT m NoContent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe Text -> ClientM NoContent
_filesMkdir (Maybe Text -> ClientM NoContent)
-> (Text -> Maybe Text) -> Text -> ClientM NoContent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe Text
forall a. a -> Maybe a
Just

-- | Move files.
mv :: MonadIO m => Text -> Text -> IpfsT m NoContent
mv :: Text -> Text -> IpfsT m NoContent
mv Text
src = ClientM NoContent -> IpfsT m NoContent
forall (m :: * -> *) a. MonadIO m => ClientM a -> IpfsT m a
call (ClientM NoContent -> IpfsT m NoContent)
-> (Text -> ClientM NoContent) -> Text -> IpfsT m NoContent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe Text -> Maybe Text -> ClientM NoContent
_filesMv (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
src) (Maybe Text -> ClientM NoContent)
-> (Text -> Maybe Text) -> Text -> ClientM NoContent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe Text
forall a. a -> Maybe a
Just

-- | Read a file in a given mfs.
read :: MonadIO m => Text -> IpfsT m FilesReadType
read :: Text -> IpfsT m Text
read = 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
. Maybe Text -> ClientM Text
_filesRead (Maybe Text -> ClientM Text)
-> (Text -> Maybe Text) -> Text -> ClientM Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe Text
forall a. a -> Maybe a
Just

-- | Display file status.
stat :: MonadIO m => Text -> IpfsT m FilesStatObj
stat :: Text -> IpfsT m FilesStatObj
stat = ClientM FilesStatObj -> IpfsT m FilesStatObj
forall (m :: * -> *) a. MonadIO m => ClientM a -> IpfsT m a
call (ClientM FilesStatObj -> IpfsT m FilesStatObj)
-> (Text -> ClientM FilesStatObj) -> Text -> IpfsT m FilesStatObj
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe Text -> ClientM FilesStatObj
_filesStat (Maybe Text -> ClientM FilesStatObj)
-> (Text -> Maybe Text) -> Text -> ClientM FilesStatObj
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe Text
forall a. a -> Maybe a
Just

-- | Remove a file.
filesRm :: MonadIO m => Text -> IpfsT m NoContent
filesRm :: Text -> IpfsT m NoContent
filesRm = ClientM NoContent -> IpfsT m NoContent
forall (m :: * -> *) a. MonadIO m => ClientM a -> IpfsT m a
call (ClientM NoContent -> IpfsT m NoContent)
-> (Text -> ClientM NoContent) -> Text -> IpfsT m NoContent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe Text -> Maybe Bool -> ClientM NoContent)
-> Maybe Bool -> Maybe Text -> ClientM NoContent
forall a b c. (a -> b -> c) -> b -> a -> c
flip Maybe Text -> Maybe Bool -> ClientM NoContent
_filesRm (Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True) (Maybe Text -> ClientM NoContent)
-> (Text -> Maybe Text) -> Text -> ClientM NoContent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe Text
forall a. a -> Maybe a
Just

-- | Write to a mutable file in a given filesystem.
write :: MonadIO m => Text -> Text -> Bool -> IpfsT m Bool
write :: Text -> Text -> Bool -> IpfsT m Bool
write Text
mfsPath Text
filePath Bool
toTruncate = Response ByteString -> Bool
forall body. Response body -> Bool
isSuccess (Response ByteString -> Bool)
-> IpfsT m (Response ByteString) -> IpfsT m Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Text -> IpfsT m (Response ByteString)
forall (m :: * -> *).
MonadIO m =>
Text -> Text -> IpfsT m (Response ByteString)
multipartCall Text
uri Text
filePath
  where
    uri :: Text
uri = Text
"files/write?arg=" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
mfsPath Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"&create=true" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"&truncate=" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (String -> Text
pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ Bool -> String
forall a. Show a => a -> String
show Bool
toTruncate)
    isSuccess :: Response body -> Bool
isSuccess = (Int
200 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==) (Int -> Bool) -> (Response body -> Int) -> Response body -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Status -> Int
statusCode (Status -> Int)
-> (Response body -> Status) -> Response body -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Response body -> Status
forall body. Response body -> Status
responseStatus