{-# LANGUAGE OverloadedStrings, ViewPatterns #-}
module Text.HTML.TagStream.Stream where

import Control.Monad (liftM)
import Data.ByteString (ByteString)
import Data.Attoparsec.Char8 (parseOnly)
import qualified Data.ByteString.Char8 as S
import qualified Data.Enumerator as E
import qualified Data.Enumerator.List as EL
import Text.HTML.TagStream.Parser
import Text.HTML.TagStream.Types

accumParse :: Monad m => ByteString -> ByteString -> m (ByteString, [Token])
accumParse acc input = liftM splitAccum $
                         either fail return $
                           parseOnly html (acc `S.append` input)
  where
    splitAccum :: [Token] -> (ByteString, [Token])
    splitAccum [] = (S.empty, [])
    splitAccum (reverse -> (Incomplete s : xs)) = (s, reverse xs)
    splitAccum tokens = (S.empty, tokens)

tokenStream :: Monad m => E.Enumeratee ByteString Token m b
tokenStream = EL.concatMapAccumM accumParse S.empty