module Main where

import Data.List
import System.Environment
import System.Exit
import System.Posix.Signals
import System.Posix.Types

import Program.Mighty (getMightyPid, sigInfo, sigReload, sigRetire, sigStop)

commandDB :: [(String, Signal)]
commandDB =
    [ ("stop", sigStop)
    , ("reload", sigReload)
    , ("retire", sigRetire)
    , ("info", sigInfo)
    ]

usage :: IO a
usage = do
    putStrLn "Usage:"
    putStrLn $ "    mightyctl " ++ cmds ++ " [pid]"
    exitFailure
  where
    cmds = intercalate "|" $ map fst commandDB

main :: IO ()
main = do
    (sig, mpid) <- getArgs >>= checkArgs
    pid <- maybe getProcessIdWithPS return mpid
    signalProcess sig pid

checkArgs :: [String] -> IO (Signal, Maybe ProcessID)
checkArgs [cmd] = do
    sig <- getSignal cmd
    return (sig, Nothing)
checkArgs [cmd, num] = do
    sig <- getSignal cmd
    pid <- getProcessId num
    return (sig, Just pid)
checkArgs _ = usage

getSignal :: String -> IO Signal
getSignal cmd = check $ lookup cmd commandDB
  where
    check (Just sig) = return sig
    check Nothing = do
        putStrLn $ "No such command: " ++ cmd
        usage

getProcessId :: String -> IO ProcessID
getProcessId num = check $ reads num
  where
    check [(pid, "")] = return . fromIntegral $ (pid :: Int)
    check _ = do
        putStrLn $ "No such process id: " ++ num
        usage

getProcessIdWithPS :: IO ProcessID
getProcessIdWithPS = getMightyPid >>= check
  where
    check [] = putStrLn "No Mighty found" >> usage
    check [pid] = return pid
    check pids = do
        putStrLn $ "Multiple Mighty found: " ++ intercalate ", " (map show pids)
        usage
