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

#include "cmCTest.h"
#include "cmCTestBuildHandler.h"
#include "cmCTestGenericHandler.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
#include "cmake.h"

#include <sstream>
#include <string.h>

class cmExecutionStatus;

cmCTestBuildCommand::cmCTestBuildCommand()
{
  this->GlobalGenerator = nullptr;
  this->Arguments[ctb_NUMBER_ERRORS] = "NUMBER_ERRORS";
  this->Arguments[ctb_NUMBER_WARNINGS] = "NUMBER_WARNINGS";
  this->Arguments[ctb_TARGET] = "TARGET";
  this->Arguments[ctb_CONFIGURATION] = "CONFIGURATION";
  this->Arguments[ctb_FLAGS] = "FLAGS";
  this->Arguments[ctb_PROJECT_NAME] = "PROJECT_NAME";
  this->Arguments[ctb_LAST] = nullptr;
  this->Last = ctb_LAST;
}

cmCTestBuildCommand::~cmCTestBuildCommand()
{
  if (this->GlobalGenerator) {
    delete this->GlobalGenerator;
    this->GlobalGenerator = nullptr;
  }
}

cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
{
  cmCTestGenericHandler* handler = this->CTest->GetInitializedHandler("build");
  if (!handler) {
    this->SetError("internal CTest error. Cannot instantiate build handler");
    return nullptr;
  }
  this->Handler = static_cast<cmCTestBuildHandler*>(handler);

  const char* ctestBuildCommand =
    this->Makefile->GetDefinition("CTEST_BUILD_COMMAND");
  if (ctestBuildCommand && *ctestBuildCommand) {
    this->CTest->SetCTestConfiguration("MakeCommand", ctestBuildCommand,
                                       this->Quiet);
  } else {
    const char* cmakeGeneratorName =
      this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR");
    const char* cmakeProjectName =
      (this->Values[ctb_PROJECT_NAME] && *this->Values[ctb_PROJECT_NAME])
      ? this->Values[ctb_PROJECT_NAME]
      : this->Makefile->GetDefinition("CTEST_PROJECT_NAME");

    // Build configuration is determined by: CONFIGURATION argument,
    // or CTEST_BUILD_CONFIGURATION script variable, or
    // CTEST_CONFIGURATION_TYPE script variable, or ctest -C command
    // line argument... in that order.
    //
    const char* ctestBuildConfiguration =
      this->Makefile->GetDefinition("CTEST_BUILD_CONFIGURATION");
    const char* cmakeBuildConfiguration =
      (this->Values[ctb_CONFIGURATION] && *this->Values[ctb_CONFIGURATION])
      ? this->Values[ctb_CONFIGURATION]
      : ((ctestBuildConfiguration && *ctestBuildConfiguration)
           ? ctestBuildConfiguration
           : this->CTest->GetConfigType().c_str());

    const char* cmakeBuildAdditionalFlags =
      (this->Values[ctb_FLAGS] && *this->Values[ctb_FLAGS])
      ? this->Values[ctb_FLAGS]
      : this->Makefile->GetDefinition("CTEST_BUILD_FLAGS");
    const char* cmakeBuildTarget =
      (this->Values[ctb_TARGET] && *this->Values[ctb_TARGET])
      ? this->Values[ctb_TARGET]
      : this->Makefile->GetDefinition("CTEST_BUILD_TARGET");

    if (cmakeGeneratorName && *cmakeGeneratorName && cmakeProjectName &&
        *cmakeProjectName) {
      if (!cmakeBuildConfiguration) {
        cmakeBuildConfiguration = "Release";
      }
      if (this->GlobalGenerator) {
        if (this->GlobalGenerator->GetName() != cmakeGeneratorName) {
          delete this->GlobalGenerator;
          this->GlobalGenerator = nullptr;
        }
      }
      if (!this->GlobalGenerator) {
        this->GlobalGenerator =
          this->Makefile->GetCMakeInstance()->CreateGlobalGenerator(
            cmakeGeneratorName);
        if (!this->GlobalGenerator) {
          std::string e = "could not create generator named \"";
          e += cmakeGeneratorName;
          e += "\"";
          this->Makefile->IssueMessage(cmake::FATAL_ERROR, e);
          cmSystemTools::SetFatalErrorOccured();
          return nullptr;
        }
      }
      if (strlen(cmakeBuildConfiguration) == 0) {
        const char* config = nullptr;
#ifdef CMAKE_INTDIR
        config = CMAKE_INTDIR;
#endif
        if (!config) {
          config = "Debug";
        }
        cmakeBuildConfiguration = config;
      }

      std::string dir = this->CTest->GetCTestConfiguration("BuildDirectory");
      std::string buildCommand =
        this->GlobalGenerator->GenerateCMakeBuildCommand(
          cmakeBuildTarget ? cmakeBuildTarget : "", cmakeBuildConfiguration,
          cmakeBuildAdditionalFlags ? cmakeBuildAdditionalFlags : "",
          this->Makefile->IgnoreErrorsCMP0061());
      cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                         "SetMakeCommand:" << buildCommand << "\n",
                         this->Quiet);
      this->CTest->SetCTestConfiguration("MakeCommand", buildCommand.c_str(),
                                         this->Quiet);
    } else {
      std::ostringstream ostr;
      /* clang-format off */
      ostr << "has no project to build. If this is a "
        "\"built with CMake\" project, verify that CTEST_CMAKE_GENERATOR "
        "and CTEST_PROJECT_NAME are set."
        "\n"
        "CTEST_PROJECT_NAME is usually set in CTestConfig.cmake. Verify "
        "that CTestConfig.cmake exists, or CTEST_PROJECT_NAME "
        "is set in the script, or PROJECT_NAME is passed as an argument "
        "to ctest_build."
        "\n"
        "Alternatively, set CTEST_BUILD_COMMAND to build the project "
        "with a custom command line.";
      /* clang-format on */
      this->SetError(ostr.str());
      return nullptr;
    }
  }

  if (const char* useLaunchers =
        this->Makefile->GetDefinition("CTEST_USE_LAUNCHERS")) {
    this->CTest->SetCTestConfiguration("UseLaunchers", useLaunchers,
                                       this->Quiet);
  }

  if (const char* labelsForSubprojects =
        this->Makefile->GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) {
    this->CTest->SetCTestConfiguration("LabelsForSubprojects",
                                       labelsForSubprojects, this->Quiet);
  }

  handler->SetQuiet(this->Quiet);
  return handler;
}

bool cmCTestBuildCommand::InitialPass(std::vector<std::string> const& args,
                                      cmExecutionStatus& status)
{
  bool ret = cmCTestHandlerCommand::InitialPass(args, status);
  if (this->Values[ctb_NUMBER_ERRORS] && *this->Values[ctb_NUMBER_ERRORS]) {
    std::ostringstream str;
    str << this->Handler->GetTotalErrors();
    this->Makefile->AddDefinition(this->Values[ctb_NUMBER_ERRORS],
                                  str.str().c_str());
  }
  if (this->Values[ctb_NUMBER_WARNINGS] &&
      *this->Values[ctb_NUMBER_WARNINGS]) {
    std::ostringstream str;
    str << this->Handler->GetTotalWarnings();
    this->Makefile->AddDefinition(this->Values[ctb_NUMBER_WARNINGS],
                                  str.str().c_str());
  }
  return ret;
}
