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

#include "cmCTest.h"
#include "cmCTestGenericHandler.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmSystemTools.h"
#include "cmWorkingDirectory.h"

#include <cstring>
#include <sstream>
#include <stdlib.h>

class cmExecutionStatus;

cmCTestHandlerCommand::cmCTestHandlerCommand()
{
  const size_t INIT_SIZE = 100;
  size_t cc;
  this->Arguments.reserve(INIT_SIZE);
  for (cc = 0; cc < INIT_SIZE; ++cc) {
    this->Arguments.push_back(nullptr);
  }
  this->Arguments[ct_RETURN_VALUE] = "RETURN_VALUE";
  this->Arguments[ct_CAPTURE_CMAKE_ERROR] = "CAPTURE_CMAKE_ERROR";
  this->Arguments[ct_SOURCE] = "SOURCE";
  this->Arguments[ct_BUILD] = "BUILD";
  this->Arguments[ct_SUBMIT_INDEX] = "SUBMIT_INDEX";
  this->Last = ct_LAST;
  this->AppendXML = false;
  this->Quiet = false;
}

namespace {
// class to save and restore the error state for ctest_* commands
// if a ctest_* command has a CAPTURE_CMAKE_ERROR then put the error
// state into there and restore the system wide error to what
// it was before the command ran
class SaveRestoreErrorState
{
public:
  SaveRestoreErrorState()
  {
    this->InitialErrorState = cmSystemTools::GetErrorOccuredFlag();
    cmSystemTools::ResetErrorOccuredFlag(); // rest the error state
    this->CaptureCMakeErrorValue = false;
  }
  // if the function has a CAPTURE_CMAKE_ERROR then we should restore
  // the error state to what it was before the function was run
  // if not then let the error state be what it is
  void CaptureCMakeError() { this->CaptureCMakeErrorValue = true; }
  ~SaveRestoreErrorState()
  {
    // if we are not saving the return value then make sure
    // if it was in error it goes back to being in error
    // otherwise leave it be what it is
    if (!this->CaptureCMakeErrorValue) {
      if (this->InitialErrorState) {
        cmSystemTools::SetErrorOccured();
      }
      return;
    }
    // if we have saved the error in a return variable
    // then put things back exactly like they were
    bool currentState = cmSystemTools::GetErrorOccuredFlag();
    // if the state changed during this command we need
    // to handle it, if not then nothing needs to be done
    if (currentState != this->InitialErrorState) {
      // restore the initial error state
      if (this->InitialErrorState) {
        cmSystemTools::SetErrorOccured();
      } else {
        cmSystemTools::ResetErrorOccuredFlag();
      }
    }
  }
  SaveRestoreErrorState(const SaveRestoreErrorState&) = delete;
  SaveRestoreErrorState& operator=(const SaveRestoreErrorState&) = delete;

private:
  bool InitialErrorState;
  bool CaptureCMakeErrorValue;
};
}

bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
                                        cmExecutionStatus& /*unused*/)
{
  // save error state and restore it if needed
  SaveRestoreErrorState errorState;
  // Allocate space for argument values.
  this->Values.clear();
  this->Values.resize(this->Last, nullptr);

  // Process input arguments.
  this->ArgumentDoing = ArgumentDoingNone;
  // look at all arguments and do not short circuit on the first
  // bad one so that CAPTURE_CMAKE_ERROR can override setting the
  // global error state
  bool foundBadArgument = false;
  for (std::string const& arg : args) {
    // Check this argument.
    if (!this->CheckArgumentKeyword(arg) && !this->CheckArgumentValue(arg)) {
      std::ostringstream e;
      e << "called with unknown argument \"" << arg << "\".";
      this->SetError(e.str());
      foundBadArgument = true;
    }
    // note bad argument
    if (this->ArgumentDoing == ArgumentDoingError) {
      foundBadArgument = true;
    }
  }
  bool capureCMakeError = (this->Values[ct_CAPTURE_CMAKE_ERROR] &&
                           *this->Values[ct_CAPTURE_CMAKE_ERROR]);
  // now that arguments are parsed check to see if there is a
  // CAPTURE_CMAKE_ERROR specified let the errorState object know.
  if (capureCMakeError) {
    errorState.CaptureCMakeError();
  }
  // if we found a bad argument then exit before running command
  if (foundBadArgument) {
    // store the cmake error
    if (capureCMakeError) {
      this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR],
                                    "-1");
      std::string const err = this->GetName() + " " + this->GetError();
      if (!cmSystemTools::FindLastString(err.c_str(), "unknown error.")) {
        cmCTestLog(this->CTest, ERROR_MESSAGE, err << " error from command\n");
      }
      // return success because failure is recorded in CAPTURE_CMAKE_ERROR
      return true;
    }
    // return failure because of bad argument
    return false;
  }

  // Set the config type of this ctest to the current value of the
  // CTEST_CONFIGURATION_TYPE script variable if it is defined.
  // The current script value trumps the -C argument on the command
  // line.
  const char* ctestConfigType =
    this->Makefile->GetDefinition("CTEST_CONFIGURATION_TYPE");
  if (ctestConfigType) {
    this->CTest->SetConfigType(ctestConfigType);
  }

  if (this->Values[ct_BUILD]) {
    this->CTest->SetCTestConfiguration(
      "BuildDirectory",
      cmSystemTools::CollapseFullPath(this->Values[ct_BUILD]).c_str(),
      this->Quiet);
  } else {
    std::string const& bdir =
      this->Makefile->GetSafeDefinition("CTEST_BINARY_DIRECTORY");
    if (!bdir.empty()) {
      this->CTest->SetCTestConfiguration(
        "BuildDirectory", cmSystemTools::CollapseFullPath(bdir).c_str(),
        this->Quiet);
    } else {
      cmCTestLog(this->CTest, ERROR_MESSAGE,
                 "CTEST_BINARY_DIRECTORY not set" << std::endl;);
    }
  }
  if (this->Values[ct_SOURCE]) {
    cmCTestLog(this->CTest, DEBUG,
               "Set source directory to: " << this->Values[ct_SOURCE]
                                           << std::endl);
    this->CTest->SetCTestConfiguration(
      "SourceDirectory",
      cmSystemTools::CollapseFullPath(this->Values[ct_SOURCE]).c_str(),
      this->Quiet);
  } else {
    this->CTest->SetCTestConfiguration(
      "SourceDirectory",
      cmSystemTools::CollapseFullPath(
        this->Makefile->GetSafeDefinition("CTEST_SOURCE_DIRECTORY"))
        .c_str(),
      this->Quiet);
  }

  if (const char* changeId =
        this->Makefile->GetDefinition("CTEST_CHANGE_ID")) {
    this->CTest->SetCTestConfiguration("ChangeId", changeId, this->Quiet);
  }

  cmCTestLog(this->CTest, DEBUG, "Initialize handler" << std::endl;);
  cmCTestGenericHandler* handler = this->InitializeHandler();
  if (!handler) {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "Cannot instantiate test handler " << this->GetName()
                                                  << std::endl);
    if (capureCMakeError) {
      this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR],
                                    "-1");
      const char* err = this->GetError();
      if (err && !cmSystemTools::FindLastString(err, "unknown error.")) {
        cmCTestLog(this->CTest, ERROR_MESSAGE, err << " error from command\n");
      }
      return true;
    }
    return false;
  }

  handler->SetAppendXML(this->AppendXML);

  handler->PopulateCustomVectors(this->Makefile);
  if (this->Values[ct_SUBMIT_INDEX]) {
    handler->SetSubmitIndex(atoi(this->Values[ct_SUBMIT_INDEX]));
  }
  cmWorkingDirectory workdir(
    this->CTest->GetCTestConfiguration("BuildDirectory"));
  if (workdir.Failed()) {
    this->SetError("failed to change directory to " +
                   this->CTest->GetCTestConfiguration("BuildDirectory") +
                   " : " + std::strerror(workdir.GetLastResult()));
    if (capureCMakeError) {
      this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR],
                                    "-1");
      cmCTestLog(this->CTest, ERROR_MESSAGE,
                 this->GetName() << " " << this->GetError() << "\n");
      // return success because failure is recorded in CAPTURE_CMAKE_ERROR
      return true;
    }
    return false;
  }

  int res = handler->ProcessHandler();
  if (this->Values[ct_RETURN_VALUE] && *this->Values[ct_RETURN_VALUE]) {
    std::ostringstream str;
    str << res;
    this->Makefile->AddDefinition(this->Values[ct_RETURN_VALUE],
                                  str.str().c_str());
  }
  this->ProcessAdditionalValues(handler);
  // log the error message if there was an error
  if (capureCMakeError) {
    const char* returnString = "0";
    if (cmSystemTools::GetErrorOccuredFlag()) {
      returnString = "-1";
      const char* err = this->GetError();
      // print out the error if it is not "unknown error" which means
      // there was no message
      if (err && !cmSystemTools::FindLastString(err, "unknown error.")) {
        cmCTestLog(this->CTest, ERROR_MESSAGE, err);
      }
    }
    // store the captured cmake error state 0 or -1
    this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR],
                                  returnString);
  }
  return true;
}

void cmCTestHandlerCommand::ProcessAdditionalValues(cmCTestGenericHandler*)
{
}

bool cmCTestHandlerCommand::CheckArgumentKeyword(std::string const& arg)
{
  // Look for non-value arguments common to all commands.
  if (arg == "APPEND") {
    this->ArgumentDoing = ArgumentDoingNone;
    this->AppendXML = true;
    return true;
  }
  if (arg == "QUIET") {
    this->ArgumentDoing = ArgumentDoingNone;
    this->Quiet = true;
    return true;
  }

  // Check for a keyword in our argument/value table.
  for (unsigned int k = 0; k < this->Arguments.size(); ++k) {
    if (this->Arguments[k] && arg == this->Arguments[k]) {
      this->ArgumentDoing = ArgumentDoingKeyword;
      this->ArgumentIndex = k;
      return true;
    }
  }
  return false;
}

bool cmCTestHandlerCommand::CheckArgumentValue(std::string const& arg)
{
  if (this->ArgumentDoing == ArgumentDoingKeyword) {
    this->ArgumentDoing = ArgumentDoingNone;
    unsigned int k = this->ArgumentIndex;
    if (this->Values[k]) {
      std::ostringstream e;
      e << "Called with more than one value for " << this->Arguments[k];
      this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
      this->ArgumentDoing = ArgumentDoingError;
      return true;
    }
    this->Values[k] = arg.c_str();
    cmCTestLog(this->CTest, DEBUG,
               "Set " << this->Arguments[k] << " to " << arg << "\n");
    return true;
  }
  return false;
}
