module Proteome.Tags.Stream where

import qualified Data.ByteString as ByteString
import qualified Data.Text as Text
import Prelude hiding (tag)
import Ribosome (Rpc)
import Ribosome.Api (optionList)
import Ribosome.Menu (MenuItem)
import qualified Streamly.Internal.Data.Fold as Fold
import Streamly.Internal.FileSystem.File (toBytes)
import qualified Streamly.Prelude as Stream
import Streamly.Prelude (SerialT)

import Proteome.Tags.Query (createTag)
import Proteome.Tags.State (RawTagSegments, Tag, TagSegments)

parseTagLine ::
  (RawTagSegments -> TagSegments) ->
  Text ->
  Maybe (MenuItem Tag)
parseTagLine :: (RawTagSegments -> TagSegments) -> Text -> Maybe (MenuItem Tag)
parseTagLine RawTagSegments -> TagSegments
mkSegments Text
l =
  case (Char -> Bool) -> Text -> [Text]
Text.split (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\t') Text
l of
    [Item [Text]
name, Item [Text]
path, String -> Maybe Int
forall a. Read a => String -> Maybe a
readMaybe (String -> Maybe Int) -> (Text -> String) -> Text -> Maybe Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
forall a. ToString a => a -> String
toString -> Just Int
line] ->
      (RawTagSegments -> TagSegments)
-> Text -> Text -> Int -> Maybe (MenuItem Tag)
createTag RawTagSegments -> TagSegments
mkSegments Text
Item [Text]
name Text
Item [Text]
path Int
line
    [Text]
_ ->
      Maybe (MenuItem Tag)
forall a. Maybe a
Nothing

readLines :: Text -> SerialT IO Text
readLines :: Text -> SerialT IO Text
readLines Text
path =
  (Word8 -> Bool)
-> Fold IO Word8 Text -> SerialT IO Word8 -> SerialT IO Text
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
(IsStream t, Monad m) =>
(a -> Bool) -> Fold m a b -> t m a -> t m b
Stream.splitOnSuffix (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
10) (ByteString -> Text
forall a b. ConvertUtf8 a b => b -> a
decodeUtf8 (ByteString -> Text) -> ([Word8] -> ByteString) -> [Word8] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Word8] -> ByteString
ByteString.pack ([Word8] -> Text) -> Fold IO Word8 [Word8] -> Fold IO Word8 Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Fold IO Word8 [Word8]
forall (m :: * -> *) a. Monad m => Fold m a [a]
Fold.toList) (String -> SerialT IO Word8
forall (t :: (* -> *) -> * -> *) (m :: * -> *).
(IsStream t, MonadCatch m, MonadAsync m) =>
String -> t m Word8
toBytes (Text -> String
forall a. ToString a => a -> String
toString Text
path))

readTags ::
  (RawTagSegments -> TagSegments) ->
  Member Rpc r =>
  Sem r (SerialT IO (MenuItem Tag))
readTags :: forall (r :: EffectRow).
(RawTagSegments -> TagSegments)
-> Member Rpc r => Sem r (SerialT IO (MenuItem Tag))
readTags RawTagSegments -> TagSegments
mkSegments = do
  [Text]
files <- Text -> Sem r [Text]
forall (r :: EffectRow). Member Rpc r => Text -> Sem r [Text]
optionList Text
"tags"
  pure ((Text -> Maybe (MenuItem Tag))
-> SerialT IO Text -> SerialT IO (MenuItem Tag)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
(IsStream t, Monad m) =>
(a -> Maybe b) -> t m a -> t m b
Stream.mapMaybe ((RawTagSegments -> TagSegments) -> Text -> Maybe (MenuItem Tag)
parseTagLine RawTagSegments -> TagSegments
mkSegments) ((Text -> SerialT IO Text) -> SerialT IO Text -> SerialT IO Text
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
(IsStream t, Monad m) =>
(a -> t m b) -> t m a -> t m b
Stream.concatMap Text -> SerialT IO Text
readLines ([Text] -> SerialT IO Text
forall (m :: * -> *) (t :: (* -> *) -> * -> *) a.
(Monad m, IsStream t) =>
[a] -> t m a
Stream.fromList [Text]
files)))