module Network.Mail.Parse.Parsers.Header where

import Network.Mail.Parse.Types
import Network.Mail.Parse.Utils
import Network.Mail.Parse.Parsers.HeaderFields (parseText)

import Data.Word8
import Data.Attoparsec.ByteString
import qualified Data.Attoparsec.ByteString as AP
import Data.Text.Encoding (decodeUtf8)
import Data.Either.Unwrap (fromRight)
import Data.Either (isRight)

import qualified Data.ByteString.Char8 as BSC

-- |Parses a header
headerParser :: Parser Header
headerParser = do
  headerN <- AP.takeWhile (/= _colon)
  word8 _colon
  AP.takeWhile isWhitespace

  headerLine <- consumeTillEndLine
  moreLines <- many' isConsequentHeaderLine

  let headerBody = decodeUtf8 . cleanupLines $ headerLine:moreLines
  let parsedBody = parseText headerBody
  let body = if isRight parsedBody then fromRight parsedBody else headerBody

  return $ Header (decodeUtf8 headerN) body

-- |Concatenate lines insterting whitespace between them.
-- The whitespace needs to be inserted as these lines
-- come from parser that eats up the whitespace
cleanupLines :: [BSC.ByteString] -> BSC.ByteString
cleanupLines ls = BSC.intercalate " " $ map BSC.init ls