{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TupleSections #-}

module Cradle.ProcessConfiguration.Helpers where

import Cradle.ProcessConfiguration
import Data.String.Conversions (ConvertibleStrings, cs)
import System.IO (Handle)

addArgs :: ConvertibleStrings s String => [s] -> ProcessConfiguration -> ProcessConfiguration
addArgs :: forall s.
ConvertibleStrings s String =>
[s] -> ProcessConfiguration -> ProcessConfiguration
addArgs [s]
args ProcessConfiguration
config =
  ProcessConfiguration
config {arguments = arguments config <> map cs args}

setStdinHandle :: Handle -> ProcessConfiguration -> ProcessConfiguration
setStdinHandle :: Handle -> ProcessConfiguration -> ProcessConfiguration
setStdinHandle Handle
handle ProcessConfiguration
config =
  ProcessConfiguration
config {stdinConfig = UseStdinHandle handle}

setNoStdin :: ProcessConfiguration -> ProcessConfiguration
setNoStdin :: ProcessConfiguration -> ProcessConfiguration
setNoStdin ProcessConfiguration
config =
  ProcessConfiguration
config {stdinConfig = NoStdinStream}

addStdoutHandle :: Handle -> ProcessConfiguration -> ProcessConfiguration
addStdoutHandle :: Handle -> ProcessConfiguration -> ProcessConfiguration
addStdoutHandle Handle
handle ProcessConfiguration
config =
  ProcessConfiguration
config {stdoutConfig = addHandle handle (stdoutConfig config)}

silenceStdout :: ProcessConfiguration -> ProcessConfiguration
silenceStdout :: ProcessConfiguration -> ProcessConfiguration
silenceStdout ProcessConfiguration
config =
  ProcessConfiguration
config {stdoutConfig = silenceDefault (stdoutConfig config)}

addStderrHandle :: Handle -> ProcessConfiguration -> ProcessConfiguration
addStderrHandle :: Handle -> ProcessConfiguration -> ProcessConfiguration
addStderrHandle Handle
handle ProcessConfiguration
config =
  ProcessConfiguration
config {stderrConfig = addHandle handle (stderrConfig config)}

silenceStderr :: ProcessConfiguration -> ProcessConfiguration
silenceStderr :: ProcessConfiguration -> ProcessConfiguration
silenceStderr ProcessConfiguration
config =
  ProcessConfiguration
config {stderrConfig = silenceDefault (stderrConfig config)}

setDelegateCtrlC :: ProcessConfiguration -> ProcessConfiguration
setDelegateCtrlC :: ProcessConfiguration -> ProcessConfiguration
setDelegateCtrlC ProcessConfiguration
config =
  ProcessConfiguration
config {delegateCtlc = True}

modifyEnvVar ::
  String ->
  (Maybe String -> Maybe String) ->
  ProcessConfiguration ->
  ProcessConfiguration
modifyEnvVar :: String
-> (Maybe String -> Maybe String)
-> ProcessConfiguration
-> ProcessConfiguration
modifyEnvVar String
name Maybe String -> Maybe String
f ProcessConfiguration
config =
  ProcessConfiguration
config
    { environmentModification =
        Just $ maybe newModification (newModification .) $ environmentModification config
    }
  where
    newModification :: [(String, String)] -> [(String, String)]
    newModification :: [(String, String)] -> [(String, String)]
newModification [(String, String)]
env =
      [(String, String)]
-> (String -> [(String, String)])
-> Maybe String
-> [(String, String)]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] ((String, String) -> [(String, String)]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((String, String) -> [(String, String)])
-> (String -> (String, String)) -> String -> [(String, String)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String
name,)) (Maybe String -> Maybe String
f (Maybe String -> Maybe String) -> Maybe String -> Maybe String
forall a b. (a -> b) -> a -> b
$ String -> [(String, String)] -> Maybe String
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup String
name [(String, String)]
env)
        [(String, String)] -> [(String, String)] -> [(String, String)]
forall a. [a] -> [a] -> [a]
++ ((String, String) -> Bool)
-> [(String, String)] -> [(String, String)]
forall a. (a -> Bool) -> [a] -> [a]
filter ((String -> String -> Bool
forall a. Eq a => a -> a -> Bool
/= String
name) (String -> Bool)
-> ((String, String) -> String) -> (String, String) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String, String) -> String
forall a b. (a, b) -> a
fst) [(String, String)]
env

setWorkingDir :: FilePath -> ProcessConfiguration -> ProcessConfiguration
setWorkingDir :: String -> ProcessConfiguration -> ProcessConfiguration
setWorkingDir String
dir ProcessConfiguration
config =
  ProcessConfiguration
config {workingDir = Just dir}