content: module Main where
  
  import Plugin.Pl.Common
  import Plugin.Pl.Optimize
  import Plugin.Pl.Parser
  import Plugin.Pl.PrettyPrinter
  import Plugin.Pl.Transform
  
  import System.Environment (getArgs)
  import System.Exit (die)
  import System.Console.GetOpt
  
  data Flag = Verbose 
            | StdIn
    deriving Eq
  
  options :: [OptDescr Flag]
  options = [ Option ['v'] ["verbose"] (NoArg Verbose) "verbose results"
            , Option []    ["stdin"]   (NoArg StdIn)   "read from stdin"
            ]
  
  header :: String
  header = "Usage: pointfree [OPTION...] query"
  
  parseArgs :: [String] -> IO ([Flag], [String])
  parseArgs args =
    case getOpt Permute options args of
      (flags, nonOptions, []) -> return (flags, nonOptions)
      (_, _, errs) -> ioError (userError (concat errs ++ usageInfo header options))
  
  getQuery :: [Flag] -> [String] -> IO String
  getQuery flags nonOptions
    | StdIn `elem` flags = getLine
    | otherwise          = return $ unwords nonOptions
  
  main :: IO ()
  main = do
    args <- getArgs
    (flags, nonOptions) <- parseArgs args
    query <- getQuery flags nonOptions
    if null query
       then putStrLn $ usageInfo header options
       else let verbose = Verbose `elem` flags
            in pf query verbose
  
  pf :: String -> Bool -> IO ()
  pf input verbose = case parsePF input of
    Right d ->
      if verbose
         then do putStrLn "Transformed to pointfree style:"
                 let d' = mapTopLevel transform d
                 putStrLn $ prettyTopLevel d'
                 putStrLn "Optimized expression:"
                 mapM_ (putStrLn . prettyTopLevel) $ mapTopLevel' optimize d'
         else putStrLn . prettyTopLevel . last . mapTopLevel' optimize $ mapTopLevel transform d
    Left err -> die err
  
  