
module Maildir where

import Data.List
import System.Directory
import System.FilePath
import System.IO
import System.IO.Unsafe

data Message = Message [Header] [Body]
    deriving Show

type Header = (String, String)

data Body = Body { contentType :: String, content :: String }
    deriving Show

getDirectoryContents' p =
    filter ((/= ".") . take 1) `fmap` getDirectoryContents p

splitOn :: (Eq a) => [a] -> [a] -> ([a], [a])
splitOn _ [] = ([], [])
splitOn needle haystack@(x:xs) =
    if needle `isPrefixOf` haystack
        then ([], drop (length needle) haystack)
        else let (a, b) = splitOn needle xs in (x:a, b)

parseMail :: String -> Message
parseMail s = let (hstr, bstr) = splitOn "\n\n" s
                  headers = map (splitOn ": ") $ lines hstr
               in Message headers [Body {
                      contentType = "text/plain",
                      content = bstr }]

readMaildir :: FilePath -> IO [Message]
readMaildir path = curPaths >>= mapM (\p -> readMail (path </> "cur" </> p))
    where curPaths = getDirectoryContents' $ path </> "cur"
          readMail p = parseMail `fmap` (unsafeInterleaveIO $ readFile p)

