{-# LANGUAGE OverloadedStrings, RecordWildCards #-}

module Data.BenchAna.Parser(parse) where

import qualified Data.ByteString.Char8 as BS
import qualified Data.Attoparsec.ByteString.Char8 as AT
import qualified Data.Attoparsec.Combinator as AT
import qualified Data.Map as M
import qualified Data.Vector.Unboxed as V
import Control.Arrow
import Data.Functor
import Data.Monoid
import Data.Maybe

import Data.BenchAna.Types

parse :: BS.ByteString -> BenchResults
parse = M.fromListWith (<>) . map (second V.singleton) . mapMaybe parseLine . BS.lines

parseLine :: BS.ByteString -> Maybe (BenchConfig, Int)
parseLine line | Right r <- AT.parseOnly lineParser line = Just r
               | otherwise = Nothing

lineParser :: AT.Parser (BenchConfig, Int)
lineParser = do
    void "QDEBUG"
    skipIncluding "bench"
    instr <- fmap BS.pack $ AT.manyTill AT.anyChar $ AT.char '('
    skipIncluding "QSize("
    width <- AT.decimal
    void ", "
    height <- AT.decimal
    time <- skipIncluding' AT.decimal
    pure (BenchConfig { dims = Dims { .. }, .. }, time)

skipIncluding :: BS.ByteString -> AT.Parser ()
skipIncluding = void . AT.manyTill AT.anyChar . AT.string

skipIncluding' :: AT.Parser a -> AT.Parser a
skipIncluding' p = AT.manyTill AT.anyChar (AT.lookAhead p) >> p
