module System.IO.Streams.Process
  ( module System.Process
  , runInteractiveCommand
  , runInteractiveProcess
  ) where
import           Data.ByteString.Char8         (ByteString)
import           System.IO                     (hClose)
import           System.Process                (CmdSpec (..), CreateProcess (CreateProcess, close_fds, cmdspec, create_group, cwd, std_err, std_in, std_out), ProcessHandle, StdStream (..), createProcess, getProcessExitCode, interruptProcessGroupOf, proc, rawSystem, readProcess, readProcessWithExitCode, runCommand, shell, showCommandForUser, system, terminateProcess, waitForProcess)
import qualified System.IO.Streams.Combinators as Streams
import qualified System.IO.Streams.Handle      as Streams
import           System.IO.Streams.Internal    (InputStream, OutputStream)
import qualified System.IO.Streams.Internal    as Streams
import qualified System.Process                as P
runInteractiveCommand :: String
                      -> IO (OutputStream ByteString,
                             InputStream ByteString,
                             InputStream ByteString,
                             ProcessHandle)
runInteractiveCommand scmd = do
    (hin, hout, herr, ph) <- P.runInteractiveCommand scmd
    sIn  <- Streams.handleToOutputStream hin >>=
            Streams.atEndOfOutput (hClose hin) >>=
            Streams.lockingOutputStream
    sOut <- Streams.handleToInputStream hout >>=
            Streams.atEndOfInput (hClose hout) >>=
            Streams.lockingInputStream
    sErr <- Streams.handleToInputStream herr >>=
            Streams.atEndOfInput (hClose herr) >>=
            Streams.lockingInputStream
    return (sIn, sOut, sErr, ph)
runInteractiveProcess
    :: FilePath                 
    -> [String]                 
    -> Maybe FilePath           
    -> Maybe [(String,String)]  
    -> IO (OutputStream ByteString,
           InputStream ByteString,
           InputStream ByteString,
           ProcessHandle)
runInteractiveProcess cmd args wd env = do
    (hin, hout, herr, ph) <- P.runInteractiveProcess cmd args wd env
    sIn  <- Streams.handleToOutputStream hin >>=
            Streams.atEndOfOutput (hClose hin) >>=
            Streams.lockingOutputStream
    sOut <- Streams.handleToInputStream hout >>=
            Streams.atEndOfInput (hClose hout) >>=
            Streams.lockingInputStream
    sErr <- Streams.handleToInputStream herr >>=
            Streams.atEndOfInput (hClose herr) >>=
            Streams.lockingInputStream
    return (sIn, sOut, sErr, ph)