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

#include "cmSystemTools.h"

#include <cmsys/Process.h>

#include <ctype.h> /* isspace */

static bool cmExecuteProcessCommandIsWhitespace(char c)
{
  return (isspace((int)c) || c == '\n' || c == '\r');
}

void cmExecuteProcessCommandFixText(std::vector<char>& output,
                                    bool strip_trailing_whitespace);
void cmExecuteProcessCommandAppend(std::vector<char>& output, const char* data,
                                   int length);

// cmExecuteProcessCommand
bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
                                          cmExecutionStatus&)
{
  if (args.empty()) {
    this->SetError("called with incorrect number of arguments");
    return false;
  }
  std::vector<std::vector<const char*> > cmds;
  std::string arguments;
  bool doing_command = false;
  size_t command_index = 0;
  bool output_quiet = false;
  bool error_quiet = false;
  bool output_strip_trailing_whitespace = false;
  bool error_strip_trailing_whitespace = false;
  std::string timeout_string;
  std::string input_file;
  std::string output_file;
  std::string error_file;
  std::string output_variable;
  std::string error_variable;
  std::string result_variable;
  std::string working_directory;
  for (size_t i = 0; i < args.size(); ++i) {
    if (args[i] == "COMMAND") {
      doing_command = true;
      command_index = cmds.size();
      cmds.push_back(std::vector<const char*>());
    } else if (args[i] == "OUTPUT_VARIABLE") {
      doing_command = false;
      if (++i < args.size()) {
        output_variable = args[i];
      } else {
        this->SetError(" called with no value for OUTPUT_VARIABLE.");
        return false;
      }
    } else if (args[i] == "ERROR_VARIABLE") {
      doing_command = false;
      if (++i < args.size()) {
        error_variable = args[i];
      } else {
        this->SetError(" called with no value for ERROR_VARIABLE.");
        return false;
      }
    } else if (args[i] == "RESULT_VARIABLE") {
      doing_command = false;
      if (++i < args.size()) {
        result_variable = args[i];
      } else {
        this->SetError(" called with no value for RESULT_VARIABLE.");
        return false;
      }
    } else if (args[i] == "WORKING_DIRECTORY") {
      doing_command = false;
      if (++i < args.size()) {
        working_directory = args[i];
      } else {
        this->SetError(" called with no value for WORKING_DIRECTORY.");
        return false;
      }
    } else if (args[i] == "INPUT_FILE") {
      doing_command = false;
      if (++i < args.size()) {
        input_file = args[i];
      } else {
        this->SetError(" called with no value for INPUT_FILE.");
        return false;
      }
    } else if (args[i] == "OUTPUT_FILE") {
      doing_command = false;
      if (++i < args.size()) {
        output_file = args[i];
      } else {
        this->SetError(" called with no value for OUTPUT_FILE.");
        return false;
      }
    } else if (args[i] == "ERROR_FILE") {
      doing_command = false;
      if (++i < args.size()) {
        error_file = args[i];
      } else {
        this->SetError(" called with no value for ERROR_FILE.");
        return false;
      }
    } else if (args[i] == "TIMEOUT") {
      doing_command = false;
      if (++i < args.size()) {
        timeout_string = args[i];
      } else {
        this->SetError(" called with no value for TIMEOUT.");
        return false;
      }
    } else if (args[i] == "OUTPUT_QUIET") {
      doing_command = false;
      output_quiet = true;
    } else if (args[i] == "ERROR_QUIET") {
      doing_command = false;
      error_quiet = true;
    } else if (args[i] == "OUTPUT_STRIP_TRAILING_WHITESPACE") {
      doing_command = false;
      output_strip_trailing_whitespace = true;
    } else if (args[i] == "ERROR_STRIP_TRAILING_WHITESPACE") {
      doing_command = false;
      error_strip_trailing_whitespace = true;
    } else if (doing_command) {
      cmds[command_index].push_back(args[i].c_str());
    } else {
      std::ostringstream e;
      e << " given unknown argument \"" << args[i] << "\".";
      this->SetError(e.str());
      return false;
    }
  }

  if (!this->Makefile->CanIWriteThisFile(output_file.c_str())) {
    std::string e = "attempted to output into a file: " + output_file +
      " into a source directory.";
    this->SetError(e);
    cmSystemTools::SetFatalErrorOccured();
    return false;
  }

  // Check for commands given.
  if (cmds.empty()) {
    this->SetError(" called with no COMMAND argument.");
    return false;
  }
  for (unsigned int i = 0; i < cmds.size(); ++i) {
    if (cmds[i].empty()) {
      this->SetError(" given COMMAND argument with no value.");
      return false;
    }
    // Add the null terminating pointer to the command argument list.
    cmds[i].push_back(CM_NULLPTR);
  }

  // Parse the timeout string.
  double timeout = -1;
  if (!timeout_string.empty()) {
    if (sscanf(timeout_string.c_str(), "%lg", &timeout) != 1) {
      this->SetError(" called with TIMEOUT value that could not be parsed.");
      return false;
    }
  }

  // Create a process instance.
  cmsysProcess* cp = cmsysProcess_New();

  // Set the command sequence.
  for (unsigned int i = 0; i < cmds.size(); ++i) {
    cmsysProcess_AddCommand(cp, &*cmds[i].begin());
  }

  // Set the process working directory.
  if (!working_directory.empty()) {
    cmsysProcess_SetWorkingDirectory(cp, working_directory.c_str());
  }

  // Always hide the process window.
  cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);

  // Check the output variables.
  bool merge_output = false;
  if (!input_file.empty()) {
    cmsysProcess_SetPipeFile(cp, cmsysProcess_Pipe_STDIN, input_file.c_str());
  }
  if (!output_file.empty()) {
    cmsysProcess_SetPipeFile(cp, cmsysProcess_Pipe_STDOUT,
                             output_file.c_str());
  }
  if (!error_file.empty()) {
    if (error_file == output_file) {
      merge_output = true;
    } else {
      cmsysProcess_SetPipeFile(cp, cmsysProcess_Pipe_STDERR,
                               error_file.c_str());
    }
  }
  if (!output_variable.empty() && output_variable == error_variable) {
    merge_output = true;
  }
  if (merge_output) {
    cmsysProcess_SetOption(cp, cmsysProcess_Option_MergeOutput, 1);
  }

  // Set the timeout if any.
  if (timeout >= 0) {
    cmsysProcess_SetTimeout(cp, timeout);
  }

  // Start the process.
  cmsysProcess_Execute(cp);

  // Read the process output.
  std::vector<char> tempOutput;
  std::vector<char> tempError;
  int length;
  char* data;
  int p;
  while ((p = cmsysProcess_WaitForData(cp, &data, &length, CM_NULLPTR), p)) {
    // Put the output in the right place.
    if (p == cmsysProcess_Pipe_STDOUT && !output_quiet) {
      if (output_variable.empty()) {
        cmSystemTools::Stdout(data, length);
      } else {
        cmExecuteProcessCommandAppend(tempOutput, data, length);
      }
    } else if (p == cmsysProcess_Pipe_STDERR && !error_quiet) {
      if (error_variable.empty()) {
        cmSystemTools::Stderr(data, length);
      } else {
        cmExecuteProcessCommandAppend(tempError, data, length);
      }
    }
  }

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

  // Fix the text in the output strings.
  cmExecuteProcessCommandFixText(tempOutput, output_strip_trailing_whitespace);
  cmExecuteProcessCommandFixText(tempError, error_strip_trailing_whitespace);

  // Store the output obtained.
  if (!output_variable.empty() && !tempOutput.empty()) {
    this->Makefile->AddDefinition(output_variable, &*tempOutput.begin());
  }
  if (!merge_output && !error_variable.empty() && !tempError.empty()) {
    this->Makefile->AddDefinition(error_variable, &*tempError.begin());
  }

  // Store the result of running the process.
  if (!result_variable.empty()) {
    switch (cmsysProcess_GetState(cp)) {
      case cmsysProcess_State_Exited: {
        int v = cmsysProcess_GetExitValue(cp);
        char buf[100];
        sprintf(buf, "%d", v);
        this->Makefile->AddDefinition(result_variable, buf);
      } break;
      case cmsysProcess_State_Exception:
        this->Makefile->AddDefinition(result_variable,
                                      cmsysProcess_GetExceptionString(cp));
        break;
      case cmsysProcess_State_Error:
        this->Makefile->AddDefinition(result_variable,
                                      cmsysProcess_GetErrorString(cp));
        break;
      case cmsysProcess_State_Expired:
        this->Makefile->AddDefinition(result_variable,
                                      "Process terminated due to timeout");
        break;
    }
  }

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

  return true;
}

void cmExecuteProcessCommandFixText(std::vector<char>& output,
                                    bool strip_trailing_whitespace)
{
  // Remove \0 characters and the \r part of \r\n pairs.
  unsigned int in_index = 0;
  unsigned int out_index = 0;
  while (in_index < output.size()) {
    char c = output[in_index++];
    if ((c != '\r' ||
         !(in_index < output.size() && output[in_index] == '\n')) &&
        c != '\0') {
      output[out_index++] = c;
    }
  }

  // Remove trailing whitespace if requested.
  if (strip_trailing_whitespace) {
    while (out_index > 0 &&
           cmExecuteProcessCommandIsWhitespace(output[out_index - 1])) {
      --out_index;
    }
  }

  // Shrink the vector to the size needed.
  output.resize(out_index);

  // Put a terminator on the text string.
  output.push_back('\0');
}

void cmExecuteProcessCommandAppend(std::vector<char>& output, const char* data,
                                   int length)
{
#if defined(__APPLE__)
  // HACK on Apple to work around bug with inserting at the
  // end of an empty vector.  This resulted in random failures
  // that were hard to reproduce.
  if (output.empty() && length > 0) {
    output.push_back(data[0]);
    ++data;
    --length;
  }
#endif
  output.insert(output.end(), data, data + length);
}
