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 qualified Network.IPFS.Remote.Error  as Remote
import           Network.IPFS.Stat.Types
import           Network.IPFS.Types         as IPFS

getStatRemote :: MonadRemoteIPFS m => IPFS.CID -> m (Either IPFS.Get.Error Stat)
getStatRemote :: forall (m :: * -> *).
MonadRemoteIPFS m =>
CID -> m (Either Error Stat)
getStatRemote CID
cid =
  forall (m :: * -> *).
MonadRemoteIPFS m =>
CID -> m (Either StatError Stat)
Remote.ipfsStat CID
cid forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Right Stat
statPayload           -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. b -> Either a b
Right Stat
statPayload
    Left (Remote.WebError ClientError
err)  -> forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$ ClientError -> Error
IPFS.Get.WebError ClientError
err
    Left (Remote.SizeError OverflowDetected
err) -> forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$ OverflowDetected -> Error
IPFS.Get.SizeError OverflowDetected
err

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

    Right Stat {Either OverflowDetected Bytes
$sel:cumulativeSize:Stat :: Stat -> Either OverflowDetected Bytes
cumulativeSize :: Either OverflowDetected Bytes
cumulativeSize} ->
      case Either OverflowDetected Bytes
cumulativeSize of
        Left OverflowDetected
err   -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$ OverflowDetected -> Error
IPFS.Get.SizeError OverflowDetected
err
        Right Bytes
size -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. b -> Either a b
Right Bytes
size

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

  Right RawMessage
contents ->
    case RawMessage -> Maybe (Integer, RawMessage)
parseSize RawMessage
contents of
      Maybe (Integer, RawMessage)
Nothing        -> forall (m :: * -> *) a. Monad m => a -> m a
return 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
$ Text
"Could not parse CumulativeSize"
      Just (Integer
size, RawMessage
_) -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. b -> Either a b
Right Integer
size

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