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

#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"

namespace {

bool MainSignature(std::vector<std::string> const& args,
                   cmExecutionStatus& status)
{
  if (args.empty()) {
    status.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;
  std::string parallel;
  enum Doing
  {
    DoingNone,
    DoingConfiguration,
    DoingProjectName,
    DoingTarget,
    DoingParallel
  };
  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 (args[i] == "PARALLEL_LEVEL") {
      doing = DoingParallel;
    } 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 if (doing == DoingParallel) {
      doing = DoingNone;
      parallel = args[i];
    } else {
      status.SetError(cmStrCat("unknown argument \"", args[i], "\""));
      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";
  }

  cmMakefile& mf = status.GetMakefile();
  if (!project_name.empty()) {
    mf.IssueMessage(MessageType::AUTHOR_WARNING,
                    "Ignoring PROJECT_NAME option because it has no effect.");
  }

  std::string makecommand = mf.GetGlobalGenerator()->GenerateCMakeBuildCommand(
    target, configuration, parallel, "", false);

  mf.AddDefinition(variable, makecommand);

  return true;
}

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

  cmMakefile& mf = status.GetMakefile();

  std::string const& define = args[0];
  cmValue cacheValue = mf.GetDefinition(define);

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

  std::string makecommand = mf.GetGlobalGenerator()->GenerateCMakeBuildCommand(
    "", configType, "", "", false);

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

} // namespace

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

  return MainSignature(args, status);
}
