module CSV.Parse
    ( parse
    ) where

import qualified Data.Attoparsec.Text as A
import qualified Data.Text as Text

import CSV.Types

-- | 'parse' parses text in the CSV format.  Delimiters are ',' and new lines.
-- | Quotation is performed with '"'.
-- | TODO: Files in the wrong format throw an error :(   
parse :: Text.Text -> CSV Text.Text
parse text =
    case A.parseOnly csvParser text of
      Left  s  -> error s
      Right c -> c

csvParser :: A.Parser (CSV Text.Text)
csvParser = do
  rows <- A.sepBy1 rowParser (A.skip A.isEndOfLine) 
  return (CSV rows)


rowParser :: A.Parser [Text.Text]
rowParser = A.sepBy1 elementParser $ A.char ','

elementParser :: A.Parser Text.Text
elementParser = do 
  text <- A.many1 $ A.choice
          [ textParser
          , quotationParser ]
  return (Text.concat text)

textParser :: A.Parser Text.Text
textParser = A.takeWhile1 (A.notInClass [',','\n', '"'])

quotationParser :: A.Parser Text.Text
quotationParser = 
    let quote = '"' in
    let f q1 t q2 = Text.cons q1 (Text.snoc t q2) in
    f <$> A.char quote <*> 
    quotedString [quote] <*>
    A.char quote

quotedString :: String ->  A.Parser Text.Text
quotedString quote = A.takeWhile (A.notInClass quote)