/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file LICENSE.rst or https://cmake.org/licensing for details.  */
#include "cmExecProgramCommand.h"

#include <cstdio>

#include "cmsys/Process.h"

#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmProcessOutput.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"

using Encoding = cmProcessOutput::Encoding;

namespace {
bool RunCommand(std::string command, std::string& output, int& retVal,
                char const* directory = nullptr, bool verbose = true,
                Encoding encoding = cmProcessOutput::Auto);
}

// cmExecProgramCommand
bool cmExecProgramCommand(std::vector<std::string> const& args,
                          cmExecutionStatus& status)
{
  if (args.empty()) {
    status.SetError("called with incorrect number of arguments");
    return false;
  }
  std::string arguments;
  bool doingargs = false;
  int count = 0;
  std::string output_variable;
  bool haveoutput_variable = false;
  std::string return_variable;
  bool havereturn_variable = false;
  for (std::string const& arg : args) {
    if (arg == "OUTPUT_VARIABLE") {
      count++;
      doingargs = false;
      havereturn_variable = false;
      haveoutput_variable = true;
    } else if (haveoutput_variable) {
      if (!output_variable.empty()) {
        status.SetError("called with incorrect number of arguments");
        return false;
      }
      output_variable = arg;
      haveoutput_variable = false;
      count++;
    } else if (arg == "RETURN_VALUE") {
      count++;
      doingargs = false;
      haveoutput_variable = false;
      havereturn_variable = true;
    } else if (havereturn_variable) {
      if (!return_variable.empty()) {
        status.SetError("called with incorrect number of arguments");
        return false;
      }
      return_variable = arg;
      havereturn_variable = false;
      count++;
    } else if (arg == "ARGS") {
      count++;
      havereturn_variable = false;
      haveoutput_variable = false;
      doingargs = true;
    } else if (doingargs) {
      arguments += arg;
      arguments += " ";
      count++;
    }
  }

  std::string command;
  if (!arguments.empty()) {
    command = cmStrCat(cmSystemTools::ConvertToRunCommandPath(args[0]), ' ',
                       arguments);
  } else {
    command = args[0];
  }
  bool verbose = true;
  if (!output_variable.empty()) {
    verbose = false;
  }
  int retVal = 0;
  std::string output;
  bool result = true;
  if (args.size() - count == 2) {
    cmSystemTools::MakeDirectory(args[1]);
    result = RunCommand(command, output, retVal, args[1].c_str(), verbose);
  } else {
    result = RunCommand(command, output, retVal, nullptr, verbose);
  }
  if (!result) {
    retVal = -1;
  }

  if (!output_variable.empty()) {
    std::string::size_type first = output.find_first_not_of(" \n\t\r");
    std::string::size_type last = output.find_last_not_of(" \n\t\r");
    if (first == std::string::npos) {
      first = 0;
    }
    if (last == std::string::npos) {
      last = output.size() - 1;
    }

    std::string coutput = std::string(output, first, last - first + 1);
    status.GetMakefile().AddDefinition(output_variable, coutput);
  }

  if (!return_variable.empty()) {
    char buffer[100];
    snprintf(buffer, sizeof(buffer), "%d", retVal);
    status.GetMakefile().AddDefinition(return_variable, buffer);
  }

  return true;
}

namespace {
bool RunCommand(std::string command, std::string& output, int& retVal,
                char const* dir, bool verbose, Encoding encoding)
{
  if (cmSystemTools::GetRunCommandOutput()) {
    verbose = false;
  }

#if defined(_WIN32) && !defined(__CYGWIN__)
  // if the command does not start with a quote, then
  // try to find the program, and if the program can not be
  // found use system to run the command as it must be a built in
  // shell command like echo or dir
  if (!command.empty() && command[0] == '\"') {
    // count the number of quotes
    int count = 0;
    for (char c : command) {
      if (c == '\"') {
        count++;
        if (count > 2) {
          break;
        }
      }
    }
    // if there are more than two double quotes use
    // GetShortPathName, the cmd.exe program in windows which
    // is used by system fails to execute if there are more than
    // one set of quotes in the arguments
    if (count > 2) {
      cmsys::RegularExpression quoted("^\"([^\"]*)\"[ \t](.*)");
      if (quoted.find(command)) {
        std::string shortCmd;
        std::string cmd = quoted.match(1);
        std::string args = quoted.match(2);
        if (!cmSystemTools::FileExists(cmd)) {
          shortCmd = cmd;
        } else if (!cmSystemTools::GetShortPath(cmd, shortCmd)) {
          cmSystemTools::Error("GetShortPath failed for " + cmd);
          return false;
        }
        shortCmd += " ";
        shortCmd += args;

        command = shortCmd;
      } else {
        cmSystemTools::Error("Could not parse command line with quotes " +
                             command);
      }
    }
  }
#endif

  // Allocate a process instance.
  cmsysProcess* cp = cmsysProcess_New();
  if (!cp) {
    cmSystemTools::Error("Error allocating process instance.");
    return false;
  }

#if defined(_WIN32) && !defined(__CYGWIN__)
  if (dir) {
    cmsysProcess_SetWorkingDirectory(cp, dir);
  }
  if (cmSystemTools::GetRunCommandHideConsole()) {
    cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
  }
  cmsysProcess_SetOption(cp, cmsysProcess_Option_Verbatim, 1);
  char const* cmd[] = { command.c_str(), nullptr };
  cmsysProcess_SetCommand(cp, cmd);
#else
  std::string commandInDir;
  if (dir) {
    commandInDir = cmStrCat("cd \"", dir, "\" && ", command);
  } else {
    commandInDir = command;
  }
#  ifndef __VMS
  commandInDir += " 2>&1";
#  endif
  command = commandInDir;
  if (verbose) {
    cmSystemTools::Stdout(cmStrCat("running ", command, '\n'));
  }
  fflush(stdout);
  fflush(stderr);
  char const* cmd[] = { "/bin/sh", "-c", command.c_str(), nullptr };
  cmsysProcess_SetCommand(cp, cmd);
#endif

  cmsysProcess_Execute(cp);

  // Read the process output.
  int length;
  char* data;
  int p;
  cmProcessOutput processOutput(encoding);
  std::string strdata;
  while ((p = cmsysProcess_WaitForData(cp, &data, &length, nullptr))) {
    if (p == cmsysProcess_Pipe_STDOUT || p == cmsysProcess_Pipe_STDERR) {
      if (verbose) {
        processOutput.DecodeText(data, length, strdata);
        cmSystemTools::Stdout(strdata);
      }
      output.append(data, length);
    }
  }

  if (verbose) {
    processOutput.DecodeText(std::string(), strdata);
    if (!strdata.empty()) {
      cmSystemTools::Stdout(strdata);
    }
  }

  // All output has been read.  Wait for the process to exit.
  cmsysProcess_WaitForExit(cp, nullptr);
  processOutput.DecodeText(output, output);

  // Check the result of running the process.
  std::string msg;
  switch (cmsysProcess_GetState(cp)) {
    case cmsysProcess_State_Exited:
      retVal = cmsysProcess_GetExitValue(cp);
      break;
    case cmsysProcess_State_Exception:
      retVal = -1;
      msg += "\nProcess terminated due to: ";
      msg += cmsysProcess_GetExceptionString(cp);
      break;
    case cmsysProcess_State_Error:
      retVal = -1;
      msg += "\nProcess failed because: ";
      msg += cmsysProcess_GetErrorString(cp);
      break;
    case cmsysProcess_State_Expired:
      retVal = -1;
      msg += "\nProcess terminated due to timeout.";
      break;
  }
  if (!msg.empty()) {
#if defined(_WIN32) && !defined(__CYGWIN__)
    // Old Windows process execution printed this info.
    msg += "\n\nfor command: ";
    msg += command;
    if (dir) {
      msg += "\nin dir: ";
      msg += dir;
    }
    msg += "\n";
    if (verbose) {
      cmSystemTools::Stdout(msg);
    }
    output += msg;
#else
    // Old UNIX process execution only put message in output.
    output += msg;
#endif
  }

  // Delete the process instance.
  cmsysProcess_Delete(cp);

  return true;
}
}
