{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes       #-}
module Distribution.Simple.Program.ResponseFile (withResponseFile) where
import Prelude ()
import System.IO (TextEncoding, hSetEncoding, hPutStr, hClose)
import Distribution.Compat.Prelude
import Distribution.Simple.Utils (TempFileOptions, withTempFileEx, debug)
import Distribution.Verbosity
withResponseFile
  :: Verbosity
  -> TempFileOptions
  -> FilePath           
  -> FilePath           
  -> Maybe TextEncoding 
  -> [String]           
  -> (FilePath -> IO a)
  -> IO a
withResponseFile verbosity tmpFileOpts workDir fileNameTemplate encoding arguments f =
  withTempFileEx tmpFileOpts workDir fileNameTemplate $ \responseFileName hf -> do
    traverse_ (hSetEncoding hf) encoding
    let responseContents = unlines $ map escapeResponseFileArg arguments
    hPutStr hf responseContents
    hClose hf
    debug verbosity $ responseFileName ++ " contents: <<<"
    debug verbosity responseContents
    debug verbosity $ ">>> " ++ responseFileName
    f responseFileName
escapeResponseFileArg :: String -> String
escapeResponseFileArg = reverse . foldl' escape []
  where
    escape :: String -> Char -> String
    escape cs c =
      case c of
        '\\'          -> c:'\\':cs
        '\''          -> c:'\\':cs
        '"'           -> c:'\\':cs
        _ | isSpace c -> c:'\\':cs
          | otherwise -> c:cs