module Network.DomainAuth.Mail.XMail (
    XMail(..)
  , initialXMail
  , pushField
  , pushBody
  , finalizeMail
  ) where

import qualified Data.ByteString.Char8 as BS
import Data.Sequence (fromList)
import Network.DomainAuth.Mail.Types
import Network.DomainAuth.Utils

----------------------------------------------------------------

-- | Type for temporary data to parse e-mail message.
data XMail = XMail {
    XMail -> Header
xmailHeader :: Header
  , XMail -> [RawBodyChunk]
xmailBody :: [RawBodyChunk]
  } deriving (XMail -> XMail -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: XMail -> XMail -> Bool
$c/= :: XMail -> XMail -> Bool
== :: XMail -> XMail -> Bool
$c== :: XMail -> XMail -> Bool
Eq,Int -> XMail -> ShowS
[XMail] -> ShowS
XMail -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [XMail] -> ShowS
$cshowList :: [XMail] -> ShowS
show :: XMail -> String
$cshow :: XMail -> String
showsPrec :: Int -> XMail -> ShowS
$cshowsPrec :: Int -> XMail -> ShowS
Show)

-- | Initial value for 'XMail'.
initialXMail :: XMail
initialXMail :: XMail
initialXMail = Header -> [RawBodyChunk] -> XMail
XMail [] []

-- | Storing field key and field value to the temporary data.
pushField :: RawFieldKey -> RawFieldValue -> XMail -> XMail
pushField :: RawBodyChunk -> RawBodyChunk -> XMail -> XMail
pushField RawBodyChunk
key RawBodyChunk
val XMail
xmail = XMail
xmail {
    xmailHeader :: Header
xmailHeader = Field
fld forall a. a -> [a] -> [a]
: XMail -> Header
xmailHeader XMail
xmail
  }
  where
    fld :: Field
fld = RawBodyChunk -> RawBodyChunk -> [RawBodyChunk] -> Field
Field RawBodyChunk
ckey RawBodyChunk
key (RawBodyChunk -> [RawBodyChunk]
blines RawBodyChunk
val)
    ckey :: RawBodyChunk
ckey = RawBodyChunk -> RawBodyChunk
canonicalizeKey RawBodyChunk
key

-- | Storing body chunk to the temporary data.
pushBody :: RawBodyChunk -> XMail -> XMail
pushBody :: RawBodyChunk -> XMail -> XMail
pushBody RawBodyChunk
bc XMail
xmail = XMail
xmail {
    xmailBody :: [RawBodyChunk]
xmailBody = RawBodyChunk
bc forall a. a -> [a] -> [a]
: XMail -> [RawBodyChunk]
xmailBody XMail
xmail
  }

-- | Converting 'XMail' to 'Mail'.
finalizeMail :: XMail -> Mail
finalizeMail :: XMail -> Mail
finalizeMail XMail
xmail = Mail {
    mailHeader :: Header
mailHeader = forall a. [a] -> [a]
reverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. XMail -> Header
xmailHeader forall a b. (a -> b) -> a -> b
$ XMail
xmail
  , mailBody :: Body
mailBody = forall a. [a] -> Seq a
fromList forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawBodyChunk -> [RawBodyChunk]
blines forall b c a. (b -> c) -> (a -> b) -> a -> c
. [RawBodyChunk] -> RawBodyChunk
BS.concat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> [a]
reverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. XMail -> [RawBodyChunk]
xmailBody forall a b. (a -> b) -> a -> b
$ XMail
xmail
  }