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

#include <sstream>

#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmStateTypes.h"
#include "cmSystemTools.h"

class cmExecutionStatus;

bool cmBuildCommand::InitialPass(std::vector<std::string> const& args,
                                 cmExecutionStatus&)
{
  // Support the legacy signature of the command:
  //
  if (2 == args.size()) {
    return this->TwoArgsSignature(args);
  }

  return this->MainSignature(args);
}

bool cmBuildCommand::MainSignature(std::vector<std::string> const& args)
{
  if (args.empty()) {
    this->SetError("requires at least one argument naming a CMake variable");
    return false;
  }

  // The cmake variable in which to store the result.
  std::string const& variable = args[0];

  // Parse remaining arguments.
  std::string configuration;
  std::string project_name;
  std::string target;
  enum Doing
  {
    DoingNone,
    DoingConfiguration,
    DoingProjectName,
    DoingTarget
  };
  Doing doing = DoingNone;
  for (unsigned int i = 1; i < args.size(); ++i) {
    if (args[i] == "CONFIGURATION") {
      doing = DoingConfiguration;
    } else if (args[i] == "PROJECT_NAME") {
      doing = DoingProjectName;
    } else if (args[i] == "TARGET") {
      doing = DoingTarget;
    } else if (doing == DoingConfiguration) {
      doing = DoingNone;
      configuration = args[i];
    } else if (doing == DoingProjectName) {
      doing = DoingNone;
      project_name = args[i];
    } else if (doing == DoingTarget) {
      doing = DoingNone;
      target = args[i];
    } else {
      std::ostringstream e;
      e << "unknown argument \"" << args[i] << "\"";
      this->SetError(e.str());
      return false;
    }
  }

  // If null/empty CONFIGURATION argument, cmake --build uses 'Debug'
  // in the currently implemented multi-configuration global generators...
  // so we put this code here to end up with the same default configuration
  // as the original 2-arg build_command signature:
  //
  if (configuration.empty()) {
    cmSystemTools::GetEnv("CMAKE_CONFIG_TYPE", configuration);
  }
  if (configuration.empty()) {
    configuration = "Release";
  }

  if (!project_name.empty()) {
    this->Makefile->IssueMessage(
      MessageType::AUTHOR_WARNING,
      "Ignoring PROJECT_NAME option because it has no effect.");
  }

  std::string makecommand =
    this->Makefile->GetGlobalGenerator()->GenerateCMakeBuildCommand(
      target, configuration, "", this->Makefile->IgnoreErrorsCMP0061());

  this->Makefile->AddDefinition(variable, makecommand);

  return true;
}

bool cmBuildCommand::TwoArgsSignature(std::vector<std::string> const& args)
{
  if (args.size() < 2) {
    this->SetError("called with less than two arguments");
    return false;
  }

  std::string const& define = args[0];
  const char* cacheValue = this->Makefile->GetDefinition(define);

  std::string configType;
  if (!cmSystemTools::GetEnv("CMAKE_CONFIG_TYPE", configType) ||
      configType.empty()) {
    configType = "Release";
  }

  std::string makecommand =
    this->Makefile->GetGlobalGenerator()->GenerateCMakeBuildCommand(
      "", configType, "", this->Makefile->IgnoreErrorsCMP0061());

  if (cacheValue) {
    return true;
  }
  this->Makefile->AddCacheDefinition(define, makecommand.c_str(),
                                     "Command used to build entire project "
                                     "from the command line.",
                                     cmStateEnums::STRING);
  return true;
}
