/* 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 "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmProperty.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.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;
  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 {
      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, "", mf.IgnoreErrorsCMP0061());

  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];
  cmProp 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, "", mf.IgnoreErrorsCMP0061());

  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);
}
