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

#include "cmCTest.h"
#include "cmCTestGenericHandler.h"
#include "cmCTestSubmitHandler.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
#include "cmake.h"

#include <sstream>

class cmExecutionStatus;

cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
{
  const char* ctestDropMethod =
    this->Makefile->GetDefinition("CTEST_DROP_METHOD");
  const char* ctestDropSite = this->Makefile->GetDefinition("CTEST_DROP_SITE");
  const char* ctestDropLocation =
    this->Makefile->GetDefinition("CTEST_DROP_LOCATION");
  const char* ctestTriggerSite =
    this->Makefile->GetDefinition("CTEST_TRIGGER_SITE");
  bool ctestDropSiteCDash = this->Makefile->IsOn("CTEST_DROP_SITE_CDASH");
  const char* ctestProjectName =
    this->Makefile->GetDefinition("CTEST_PROJECT_NAME");
  if (!ctestDropMethod) {
    ctestDropMethod = "http";
  }

  if (!ctestDropSite) {
    // error: CDash requires CTEST_DROP_SITE definition
    // in CTestConfig.cmake
  }
  if (!ctestDropLocation) {
    // error: CDash requires CTEST_DROP_LOCATION definition
    // in CTestConfig.cmake
  }
  this->CTest->SetCTestConfiguration("ProjectName", ctestProjectName,
                                     this->Quiet);
  this->CTest->SetCTestConfiguration("DropMethod", ctestDropMethod,
                                     this->Quiet);
  this->CTest->SetCTestConfiguration("DropSite", ctestDropSite, this->Quiet);
  this->CTest->SetCTestConfiguration("DropLocation", ctestDropLocation,
                                     this->Quiet);

  this->CTest->SetCTestConfiguration(
    "IsCDash", ctestDropSiteCDash ? "TRUE" : "FALSE", this->Quiet);

  // Only propagate TriggerSite for non-CDash projects:
  //
  if (!ctestDropSiteCDash) {
    this->CTest->SetCTestConfiguration("TriggerSite", ctestTriggerSite,
                                       this->Quiet);
  }

  this->CTest->SetCTestConfigurationFromCMakeVariable(
    this->Makefile, "CurlOptions", "CTEST_CURL_OPTIONS", this->Quiet);
  this->CTest->SetCTestConfigurationFromCMakeVariable(
    this->Makefile, "DropSiteUser", "CTEST_DROP_SITE_USER", this->Quiet);
  this->CTest->SetCTestConfigurationFromCMakeVariable(
    this->Makefile, "DropSitePassword", "CTEST_DROP_SITE_PASSWORD",
    this->Quiet);
  this->CTest->SetCTestConfigurationFromCMakeVariable(
    this->Makefile, "ScpCommand", "CTEST_SCP_COMMAND", this->Quiet);

  const char* notesFilesVariable =
    this->Makefile->GetDefinition("CTEST_NOTES_FILES");
  if (notesFilesVariable) {
    std::vector<std::string> notesFiles;
    cmCTest::VectorOfStrings newNotesFiles;
    cmSystemTools::ExpandListArgument(notesFilesVariable, notesFiles);
    newNotesFiles.insert(newNotesFiles.end(), notesFiles.begin(),
                         notesFiles.end());
    this->CTest->GenerateNotesFile(newNotesFiles);
  }

  const char* extraFilesVariable =
    this->Makefile->GetDefinition("CTEST_EXTRA_SUBMIT_FILES");
  if (extraFilesVariable) {
    std::vector<std::string> extraFiles;
    cmCTest::VectorOfStrings newExtraFiles;
    cmSystemTools::ExpandListArgument(extraFilesVariable, extraFiles);
    newExtraFiles.insert(newExtraFiles.end(), extraFiles.begin(),
                         extraFiles.end());
    if (!this->CTest->SubmitExtraFiles(newExtraFiles)) {
      this->SetError("problem submitting extra files.");
      return nullptr;
    }
  }

  cmCTestGenericHandler* handler =
    this->CTest->GetInitializedHandler("submit");
  if (!handler) {
    this->SetError("internal CTest error. Cannot instantiate submit handler");
    return nullptr;
  }

  // If no FILES or PARTS given, *all* PARTS are submitted by default.
  //
  // If FILES are given, but not PARTS, only the FILES are submitted
  // and *no* PARTS are submitted.
  //  (This is why we select the empty "noParts" set in the
  //   FilesMentioned block below...)
  //
  // If PARTS are given, only the selected PARTS are submitted.
  //
  // If both PARTS and FILES are given, only the selected PARTS *and*
  // all the given FILES are submitted.

  // If given explicit FILES to submit, pass them to the handler.
  //
  if (this->FilesMentioned) {
    // Intentionally select *no* PARTS. (Pass an empty set.) If PARTS
    // were also explicitly mentioned, they will be selected below...
    // But FILES with no PARTS mentioned should just submit the FILES
    // without any of the default parts.
    //
    std::set<cmCTest::Part> noParts;
    static_cast<cmCTestSubmitHandler*>(handler)->SelectParts(noParts);

    static_cast<cmCTestSubmitHandler*>(handler)->SelectFiles(this->Files);
  }

  // If a PARTS option was given, select only the named parts for submission.
  //
  if (this->PartsMentioned) {
    static_cast<cmCTestSubmitHandler*>(handler)->SelectParts(this->Parts);
  }

  // Pass along any HTTPHEADER to the handler if this option was given.
  if (!this->HttpHeaders.empty()) {
    static_cast<cmCTestSubmitHandler*>(handler)->SetHttpHeaders(
      this->HttpHeaders);
  }

  static_cast<cmCTestSubmitHandler*>(handler)->SetOption(
    "RetryDelay", this->RetryDelay.c_str());
  static_cast<cmCTestSubmitHandler*>(handler)->SetOption(
    "RetryCount", this->RetryCount.c_str());
  static_cast<cmCTestSubmitHandler*>(handler)->SetOption(
    "InternalTest", this->InternalTest ? "ON" : "OFF");

  handler->SetQuiet(this->Quiet);

  if (this->CDashUpload) {
    static_cast<cmCTestSubmitHandler*>(handler)->SetOption(
      "CDashUploadFile", this->CDashUploadFile.c_str());
    static_cast<cmCTestSubmitHandler*>(handler)->SetOption(
      "CDashUploadType", this->CDashUploadType.c_str());
  }
  return handler;
}

bool cmCTestSubmitCommand::InitialPass(std::vector<std::string> const& args,
                                       cmExecutionStatus& status)
{
  this->CDashUpload = !args.empty() && args[0] == "CDASH_UPLOAD";
  return this->cmCTestHandlerCommand::InitialPass(args, status);
}

bool cmCTestSubmitCommand::CheckArgumentKeyword(std::string const& arg)
{
  if (this->CDashUpload) {
    // Arguments specific to the CDASH_UPLOAD signature.
    if (arg == "CDASH_UPLOAD") {
      this->ArgumentDoing = ArgumentDoingCDashUpload;
      return true;
    }

    if (arg == "CDASH_UPLOAD_TYPE") {
      this->ArgumentDoing = ArgumentDoingCDashUploadType;
      return true;
    }
  } else {
    // Arguments that cannot be used with CDASH_UPLOAD.
    if (arg == "PARTS") {
      this->ArgumentDoing = ArgumentDoingParts;
      this->PartsMentioned = true;
      return true;
    }

    if (arg == "FILES") {
      this->ArgumentDoing = ArgumentDoingFiles;
      this->FilesMentioned = true;
      return true;
    }
  }
  // Arguments used by both modes.
  if (arg == "HTTPHEADER") {
    this->ArgumentDoing = ArgumentDoingHttpHeader;
    return true;
  }

  if (arg == "RETRY_COUNT") {
    this->ArgumentDoing = ArgumentDoingRetryCount;
    return true;
  }

  if (arg == "RETRY_DELAY") {
    this->ArgumentDoing = ArgumentDoingRetryDelay;
    return true;
  }

  if (arg == "INTERNAL_TEST_CHECKSUM") {
    this->InternalTest = true;
    return true;
  }

  // Look for other arguments.
  return this->Superclass::CheckArgumentKeyword(arg);
}

bool cmCTestSubmitCommand::CheckArgumentValue(std::string const& arg)
{
  // Handle states specific to this command.
  if (this->ArgumentDoing == ArgumentDoingParts) {
    cmCTest::Part p = this->CTest->GetPartFromName(arg.c_str());
    if (p != cmCTest::PartCount) {
      this->Parts.insert(p);
    } else {
      std::ostringstream e;
      e << "Part name \"" << arg << "\" is invalid.";
      this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
      this->ArgumentDoing = ArgumentDoingError;
    }
    return true;
  }

  if (this->ArgumentDoing == ArgumentDoingFiles) {
    if (cmSystemTools::FileExists(arg)) {
      this->Files.insert(arg);
    } else {
      std::ostringstream e;
      e << "File \"" << arg << "\" does not exist. Cannot submit "
        << "a non-existent file.";
      this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
      this->ArgumentDoing = ArgumentDoingError;
    }
    return true;
  }

  if (this->ArgumentDoing == ArgumentDoingHttpHeader) {
    this->HttpHeaders.push_back(arg);
    return true;
  }

  if (this->ArgumentDoing == ArgumentDoingRetryCount) {
    this->RetryCount = arg;
    return true;
  }

  if (this->ArgumentDoing == ArgumentDoingRetryDelay) {
    this->RetryDelay = arg;
    return true;
  }

  if (this->ArgumentDoing == ArgumentDoingCDashUpload) {
    this->ArgumentDoing = ArgumentDoingNone;
    this->CDashUploadFile = arg;
    return true;
  }

  if (this->ArgumentDoing == ArgumentDoingCDashUploadType) {
    this->ArgumentDoing = ArgumentDoingNone;
    this->CDashUploadType = arg;
    return true;
  }

  // Look for other arguments.
  return this->Superclass::CheckArgumentValue(arg);
}
