import Data.Char
import Text.Regex
import Text.ParserCombinators.Parsec
import Data
import GccOptArg
import JavacOptArg
import MvOpt

import ParseOption
import ParseArgument

cmdSymbol = char '/'

parseCmd :: Parser Cmd
parseCmd = do xs <- many1 (alphaNum <|> cmdSymbol)
              spaces
              return $ Cmd xs


optParserSelector (Cmd "gcc") = parseGccOptArg
optParserSelector (Cmd "javac") = parseJavacOptArg
optParserSelector (Cmd "mv") = parseMvOptArg
optParserSelector _ = parseOpt

line = do command <- parseCmd
          spaces
          optAndArg <- many (try (optParserSelector command) <|> parseOpt)
          cmdArg <- many parseArgument
          return $ Line command optAndArg cmdArg 


noGeneration [Option _ _ ] = ""

generation (Cmd "gcc") = gccGeneration
generation _ = noGeneration

format (Right ys) = ys 

formatopt [] = "WithoutOption"
formatopt opts =   (reverse $ tail$ tail $reverse $show $filter (/='"') $ show (concatMap optFormat opts)) ++ ['"']

formatarg args = (reverse $ tail$ tail $reverse $show (concatMap argFormat args)) ++ ['"']

convert (num ,(Line (Cmd "mv") opts args)) = show num ++ "[shape = Mrecord ,style = dashed,label = \"{mv|line"++show num ++"}\"]; \n"  ++ formatopt opts ++ "[shape = box, style = dashed]; \n" ++show num ++ " -> " ++ formatopt opts ++ "->" ++ formatarg args

convert (num ,(Line (Cmd "javac") opts [])) = ""
convert (num ,(Line (Cmd "javac") opts (arg:args))) =  show num ++"[shape = Mrecord ,style = dashed,label = \"{javac|line"++show num ++"}\"]; \n" ++ formatopt opts ++ "[shape = box, style = dashed]; \n" ++formatarg [arg] ++ " -> " ++ show num  ++ " -> " ++ formatopt opts ++ " -> "  ++show ((reverse $ dropWhile (/='.') $ reverse $ concatMap argFormat args)  ++ "class") ++ convert (num,(Line (Cmd "javac") opts args))

convert (num,(Line (Cmd "gcc") opts [])) = show num ++"[shape = Mrecord ,style = dashed,label = \"{gcc|line"++show num ++"}\"]; \n" ++ formatopt opts ++ "[shape = box, style = dashed]; \n" ++ show num  ++ " -> " ++ formatopt opts ++ " -> "  ++ show (generation (Cmd "gcc") opts) ++"\n"

convert (num,(Line (Cmd "gcc") opts (arg:args))) = show num ++"[shape = Mrecord, style = dashed,label = \"{gcc|line"++show num ++"}\"]; \n" ++formatarg [arg] ++ " -> " ++ show num ++"\n" ++ convert (num,(Line (Cmd "gcc") opts args))

convert (num,(Line cmd opts args)) =cmdFormat cmd ++"[style = dashed]; \n" ++ formatopt opts ++ "[shape = box, style = dashed]; \n" ++ formatarg args ++ " -> " ++ show (cmdFormat cmd) ++ " -> "  ++ formatopt opts ++ " -> "  ++ show (generation cmd opts)



run xs = 
  do file <- readFile $ xs
     let lineStr = lines file
     mapM_ print $ map (format) $ map (parse line  "error") lineStr
     writeFile "result.txt" $ unlines $ map show $ map (format) $ map (parse line "error") lineStr
     writeFile "graph.dot" $ "digraph result { \n graph [rankdir = LR];" ++ (unlines $ map convert $ zip [1..] (map format $ map (parse line  "error") lineStr)) ++ "}"


