{- DisTract ------------------------------------------------------\
 |                                                                 |
 | Copyright (c) 2007, Matthew Sackman (matthew@wellquite.org)     |
 |                                                                 |
 | DisTract is freely distributable under the terms of a 3-Clause  |
 | BSD-style license. For details, see the DisTract web site:      |
 |   http://distract.wellquite.org/                                |
 |                                                                 |
 \-----------------------------------------------------------------}

module DisTract.BugFileInputLoader
    (parseForNewBug,
     parseForBugUpdate
    )
where

import DisTract.Types
import DisTract.Parsers
import DisTract.Utils
import qualified Data.Map as M
import qualified JSON as J
import Control.Monad

parseForNewBug :: FilePath -> IO (Maybe (String, M.Map String J.Value))
parseForNewBug file
    -- must readFileStrict because we're going to write to it afterwards.
    = do { textJson <- readFileStrict file
         ; case J.parse textJson of
             (Just (J.Object obj)) ->
                 return $ Just (comment, fields)
                     where
                       commentM = M.lookup "text" obj
                       fieldsM = M.lookup "fields" obj
                       comment = case commentM of
                                   (Just (J.String txt)) -> txt
                                   _ -> ""
                       fields = case fieldsM of
                                  (Just (J.Object objFields)) -> objFields
                                  _ -> M.empty
             _ -> return Nothing
         }

parseForBugUpdate :: FilePath -> IO (Maybe (BugId, Maybe (String, String), M.Map String J.Value))
parseForBugUpdate file
    = do { textJson <- readFile file
         ; case J.parse textJson of
             (Just (J.Object obj)) -> return $ fmap (\bugId -> (bugId, comment, fields)) bid
                 where
                   bidM = M.lookup "bugId" obj
                   commentM = M.lookup "comment" obj
                   fieldsM = M.lookup "fields" obj
                   bid = join . fmap findBugIdJson $ bidM
                   comment' = case commentM of
                                (Just (J.Object cObj)) ->
                                    liftM2 (,) txtM inReplyToM
                                        where
                                          txtM = M.lookup "text" cObj
                                          inReplyToM = M.lookup "inReplyTo" cObj
                                _ -> Nothing
                   comment = join . fmap commentBuilder $ comment'
                   commentBuilder :: (J.Value, J.Value) -> Maybe (String, String)
                   commentBuilder ((J.String txt), (J.String inReplyTo)) = Just (txt, inReplyTo)
                   commentBuilder _ = Nothing
                   fields = case fieldsM of
                              (Just (J.Object objFields)) -> objFields
                              _ -> M.empty
             _ -> return Nothing
         }

findBugIdJson :: J.Value -> Maybe BugId
findBugIdJson (J.String txt) = case result of
                                 (Left _) -> Nothing
                                 (Right r) -> Just r
    where
      result = findBugId txt
findBugIdJson _ = Nothing