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

#include "cmsys/Process.h"
#include <stdio.h>

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

class cmExecutionStatus;

// cmExecProgramCommand
bool cmExecProgramCommand::InitialPass(std::vector<std::string> const& args,
                                       cmExecutionStatus&)
{
  if (args.empty()) {
    this->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()) {
        this->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()) {
        this->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 = cmSystemTools::ConvertToRunCommandPath(args[0]);
    command += " ";
    command += 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 = cmExecProgramCommand::RunCommand(command, output, retVal,
                                              args[1].c_str(), verbose);
  } else {
    result = cmExecProgramCommand::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);
    this->Makefile->AddDefinition(output_variable, coutput);
  }

  if (!return_variable.empty()) {
    char buffer[100];
    sprintf(buffer, "%d", retVal);
    this->Makefile->AddDefinition(return_variable, buffer);
  }

  return true;
}

bool cmExecProgramCommand::RunCommand(std::string command, std::string& output,
                                      int& retVal, const char* 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);
  const char* cmd[] = { command.c_str(), nullptr };
  cmsysProcess_SetCommand(cp, cmd);
#else
  std::string commandInDir;
  if (dir) {
    commandInDir = "cd \"";
    commandInDir += dir;
    commandInDir += "\" && ";
    commandInDir += command;
  } else {
    commandInDir = command;
  }
#  ifndef __VMS
  commandInDir += " 2>&1";
#  endif
  command = commandInDir;
  if (verbose) {
    cmSystemTools::Stdout("running ");
    cmSystemTools::Stdout(command);
    cmSystemTools::Stdout("\n");
  }
  fflush(stdout);
  fflush(stderr);
  const char* 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;
}
