content: 
  {-
  Simple command line tool to experiment with simple-sql-parser
  
  Commands:
  
  parse: parse sql from file, stdin or from command line
  lex: lex sql same
  indent: parse then pretty print sql
  
  TODO: this is supposed to be a simple example, but it's a total mess
  write some simple helpers so it's all in text?
  
  -}
  
  {-# LANGUAGE TupleSections #-}
  import System.Environment (getArgs)
  import Control.Monad (forM_, when)
  import Data.Maybe (isJust)
  import System.Exit (exitFailure)
  import Data.List (intercalate)
  import Text.Show.Pretty (ppShow)
  --import Control.Applicative
  
  import qualified Data.Text as T
  
  import Language.SQL.SimpleSQL.Pretty
      (prettyStatements)
  import Language.SQL.SimpleSQL.Parse
      (parseStatements
      ,prettyError)
  import qualified Language.SQL.SimpleSQL.Lex as L
  import Language.SQL.SimpleSQL.Dialect (ansi2011)
  
  
  main :: IO ()
  main = do
      args <- getArgs
      case args of
          [] -> do
                -- exit with 0 in this case
                showHelp Nothing --  $ Just "no command given"
          (c:as) -> do
               let cmd = lookup c commands
               maybe (showHelp (Just "command not recognised"))
                     (\(_,cmd') -> cmd' as)
                     cmd
  
  commands :: [(String, (String,[String] -> IO ()))]
  commands =
      [("help", helpCommand)
      ,("parse", parseCommand)
      ,("lex", lexCommand)
      ,("format", formatCommand)]
  
  showHelp :: Maybe String -> IO ()
  showHelp msg = do
            maybe (return ()) (\e -> putStrLn $ "Error: " ++ e) msg
            putStrLn "Usage:\n SimpleSQLParserTool command args"
            forM_ commands $ \(c, (h,_)) -> do
                 putStrLn $ c ++ "\t" ++ h
            when (isJust msg) $ exitFailure
  
  helpCommand :: (String,[String] -> IO ())
  helpCommand =
      ("show help for this progam", \_ -> showHelp Nothing)
  
  getInput :: [String] -> IO (FilePath,String)
  getInput as =
      case as of
        ["-"] -> ("",) <$> getContents
        ("-c":as') -> return ("", unwords as')
        [filename] -> (filename,) <$> readFile filename
        _ -> showHelp (Just "arguments not recognised") >> error ""
  
  parseCommand :: (String,[String] -> IO ())
  parseCommand =
    ("parse SQL from file/stdin/command line (use -c to parse from command line)"
    ,\args -> do
        (f,src) <- getInput args
        either (error . T.unpack . prettyError)
            (putStrLn . ppShow)
            $ parseStatements ansi2011 (T.pack f) Nothing (T.pack src)
    )
  
  lexCommand :: (String,[String] -> IO ())
  lexCommand =
    ("lex SQL from file/stdin/command line (use -c to parse from command line)"
    ,\args -> do
        (f,src) <- getInput args
        either (error . T.unpack . L.prettyError)
               (putStrLn . intercalate ",\n" . map show)
               $ L.lexSQL ansi2011 False (T.pack f) Nothing (T.pack src)
    )
  
  
  formatCommand :: (String,[String] -> IO ())
  formatCommand =
    ("parse then pretty print SQL from file/stdin/command line (use -c to parse from command line)"
    ,\args -> do
        (f,src) <- getInput args
        either (error . T.unpack . prettyError)
            (putStrLn . T.unpack . prettyStatements ansi2011)
            $ parseStatements ansi2011 (T.pack f) Nothing (T.pack src)
  
    )
  