module Network.IPFS.Stat
  ( getStatRemote
  , getSizeRemote
  , getSize
  , module Network.IPFS.Stat.Types
  ) where

import           Data.ByteString.Lazy.Char8 as CL

import qualified RIO.ByteString.Lazy        as Lazy
import qualified RIO.List                   as List

import qualified Network.IPFS.Internal.UTF8 as UTF8
import           Network.IPFS.Local.Class   as IPFS
import           Network.IPFS.Prelude
import           Network.IPFS.Remote.Class  as Remote

import           Network.IPFS.Get.Error     as IPFS.Get
import qualified Network.IPFS.Process.Error as Process

import           Network.IPFS.Bytes.Types
import           Network.IPFS.Stat.Types
import           Network.IPFS.Types         as IPFS

getStatRemote :: MonadRemoteIPFS m => IPFS.CID -> m (Either IPFS.Get.Error Stat)
getStatRemote :: CID -> m (Either Error Stat)
getStatRemote CID
cid =
  CID -> m (Either ClientError Stat)
forall (m :: * -> *).
MonadRemoteIPFS m =>
CID -> m (Either ClientError Stat)
Remote.ipfsStat CID
cid m (Either ClientError Stat)
-> (Either ClientError Stat -> m (Either Error Stat))
-> m (Either Error Stat)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Left ClientError
err   -> Either Error Stat -> m (Either Error Stat)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Error Stat -> m (Either Error Stat))
-> (Text -> Either Error Stat) -> Text -> m (Either Error Stat)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Error -> Either Error Stat
forall a b. a -> Either a b
Left (Error -> Either Error Stat)
-> (Text -> Error) -> Text -> Either Error Stat
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Error
UnexpectedOutput (Text -> m (Either Error Stat)) -> Text -> m (Either Error Stat)
forall a b. (a -> b) -> a -> b
$ ClientError -> Text
forall a. Show a => a -> Text
UTF8.textShow ClientError
err
    Right Stat
stat -> Either Error Stat -> m (Either Error Stat)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Error Stat -> m (Either Error Stat))
-> Either Error Stat -> m (Either Error Stat)
forall a b. (a -> b) -> a -> b
$ Stat -> Either Error Stat
forall a b. b -> Either a b
Right Stat
stat

getSizeRemote :: MonadRemoteIPFS m => IPFS.CID -> m (Either IPFS.Get.Error Bytes)
getSizeRemote :: CID -> m (Either Error Bytes)
getSizeRemote CID
cid =
  CID -> m (Either Error Stat)
forall (m :: * -> *).
MonadRemoteIPFS m =>
CID -> m (Either Error Stat)
getStatRemote CID
cid m (Either Error Stat)
-> (Either Error Stat -> m (Either Error Bytes))
-> m (Either Error Bytes)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Left Error
err   -> Either Error Bytes -> m (Either Error Bytes)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Error Bytes -> m (Either Error Bytes))
-> Either Error Bytes -> m (Either Error Bytes)
forall a b. (a -> b) -> a -> b
$ Error -> Either Error Bytes
forall a b. a -> Either a b
Left Error
err
    Right Stat
stat -> Either Error Bytes -> m (Either Error Bytes)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Error Bytes -> m (Either Error Bytes))
-> (Bytes -> Either Error Bytes) -> Bytes -> m (Either Error Bytes)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bytes -> Either Error Bytes
forall a b. b -> Either a b
Right (Bytes -> m (Either Error Bytes))
-> Bytes -> m (Either Error Bytes)
forall a b. (a -> b) -> a -> b
$ Stat -> Bytes
cumulativeSize Stat
stat

getSize :: MonadLocalIPFS m => IPFS.CID -> m (Either IPFS.Get.Error Integer)
getSize :: CID -> m (Either Error Integer)
getSize cid :: CID
cid@(CID Text
hash) = [Opt] -> ByteString -> m (Either Error ByteString)
forall (m :: * -> *).
MonadLocalIPFS m =>
[Opt] -> ByteString -> m (Either Error ByteString)
IPFS.runLocal [Item [Opt]
"object", Item [Opt]
"stat"] (ByteString -> ByteString
Lazy.fromStrict (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
<| Text -> ByteString
encodeUtf8 Text
hash) m (Either Error ByteString)
-> (Either Error ByteString -> m (Either Error Integer))
-> m (Either Error Integer)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
  Left Error
err -> case Error
err of
    Process.Timeout Natural
secs   -> Either Error Integer -> m (Either Error Integer)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Error Integer -> m (Either Error Integer))
-> (Error -> Either Error Integer)
-> Error
-> m (Either Error Integer)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Error -> Either Error Integer
forall a b. a -> Either a b
Left (Error -> m (Either Error Integer))
-> Error -> m (Either Error Integer)
forall a b. (a -> b) -> a -> b
$ CID -> Natural -> Error
TimedOut CID
cid Natural
secs
    Process.UnknownErr ByteString
raw -> Either Error Integer -> m (Either Error Integer)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Error Integer -> m (Either Error Integer))
-> (Text -> Either Error Integer)
-> Text
-> m (Either Error Integer)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Error -> Either Error Integer
forall a b. a -> Either a b
Left (Error -> Either Error Integer)
-> (Text -> Error) -> Text -> Either Error Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Error
UnknownErr (Text -> m (Either Error Integer))
-> Text -> m (Either Error Integer)
forall a b. (a -> b) -> a -> b
$ ByteString -> Text
forall a. Show a => a -> Text
UTF8.textShow ByteString
raw

  Right ByteString
contents ->
    case ByteString -> Maybe (Integer, ByteString)
parseSize ByteString
contents of
      Maybe (Integer, ByteString)
Nothing        -> Either Error Integer -> m (Either Error Integer)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Error Integer -> m (Either Error Integer))
-> (Text -> Either Error Integer)
-> Text
-> m (Either Error Integer)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Error -> Either Error Integer
forall a b. a -> Either a b
Left (Error -> Either Error Integer)
-> (Text -> Error) -> Text -> Either Error Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Error
UnexpectedOutput (Text -> m (Either Error Integer))
-> Text -> m (Either Error Integer)
forall a b. (a -> b) -> a -> b
$ Text
"Could not parse CumulativeSize"
      Just (Integer
size, ByteString
_) -> Either Error Integer -> m (Either Error Integer)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Error Integer -> m (Either Error Integer))
-> Either Error Integer -> m (Either Error Integer)
forall a b. (a -> b) -> a -> b
$ Integer -> Either Error Integer
forall a b. b -> Either a b
Right Integer
size

parseSize :: Lazy.ByteString -> Maybe (Integer, Lazy.ByteString)
parseSize :: ByteString -> Maybe (Integer, ByteString)
parseSize ByteString
lbs = do
  ByteString
finalLine <- [ByteString] -> Maybe ByteString
forall a. [a] -> Maybe a
List.lastMaybe ([ByteString] -> Maybe ByteString)
-> [ByteString] -> Maybe ByteString
forall a b. (a -> b) -> a -> b
$ ByteString -> [ByteString]
CL.lines ByteString
lbs
  ByteString
finalWord <- [ByteString] -> Maybe ByteString
forall a. [a] -> Maybe a
List.lastMaybe ([ByteString] -> Maybe ByteString)
-> [ByteString] -> Maybe ByteString
forall a b. (a -> b) -> a -> b
$ ByteString -> [ByteString]
CL.words ByteString
finalLine
  ByteString -> Maybe (Integer, ByteString)
CL.readInteger ByteString
finalWord