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

#include <algorithm>
#include <iterator>

#include <cmext/string_view>

#include "cmArgumentParser.h"
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmProperty.h"
#include "cmRange.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"

bool cmDefinePropertyCommand(std::vector<std::string> const& args,
                             cmExecutionStatus& status)
{
  if (args.empty()) {
    status.SetError("called with incorrect number of arguments");
    return false;
  }

  // Get the scope in which to define the property.
  cmProperty::ScopeType scope;
  std::string const& scope_arg = args[0];

  if (scope_arg == "GLOBAL") {
    scope = cmProperty::GLOBAL;
  } else if (scope_arg == "DIRECTORY") {
    scope = cmProperty::DIRECTORY;
  } else if (scope_arg == "TARGET") {
    scope = cmProperty::TARGET;
  } else if (scope_arg == "SOURCE") {
    scope = cmProperty::SOURCE_FILE;
  } else if (scope_arg == "TEST") {
    scope = cmProperty::TEST;
  } else if (scope_arg == "VARIABLE") {
    scope = cmProperty::VARIABLE;
  } else if (scope_arg == "CACHED_VARIABLE") {
    scope = cmProperty::CACHED_VARIABLE;
  } else {
    status.SetError(cmStrCat("given invalid scope ", scope_arg,
                             ".  Valid scopes are GLOBAL, DIRECTORY, TARGET, "
                             "SOURCE, TEST, VARIABLE, CACHED_VARIABLE."));
    return false;
  }

  // Parse remaining arguments.
  bool inherited = false;
  std::string PropertyName;
  std::vector<std::string> BriefDocs;
  std::vector<std::string> FullDocs;
  std::string initializeFromVariable;

  cmArgumentParser<void> parser;
  parser.Bind("PROPERTY"_s, PropertyName);
  parser.Bind("BRIEF_DOCS"_s, BriefDocs);
  parser.Bind("FULL_DOCS"_s, FullDocs);
  parser.Bind("INHERITED"_s, inherited);
  parser.Bind("INITIALIZE_FROM_VARIABLE"_s, initializeFromVariable);
  std::vector<std::string> invalidArgs;

  parser.Parse(cmMakeRange(args).advance(1), &invalidArgs);
  if (!invalidArgs.empty()) {
    status.SetError(
      cmStrCat("given invalid argument \"", invalidArgs.front(), "\"."));
    return false;
  }

  // Make sure a property name was found.
  if (PropertyName.empty()) {
    status.SetError("not given a PROPERTY <name> argument.");
    return false;
  }

  if (!initializeFromVariable.empty()) {
    // Make sure property scope is TARGET.
    if (scope != cmProperty::TARGET) {
      status.SetError(
        "Scope must be TARGET if INITIALIZE_FROM_VARIABLE is specified");
      return false;
    }

    // Make sure the variable has the property name as a suffix.
    if (!cmHasSuffix(initializeFromVariable, PropertyName)) {
      status.SetError(cmStrCat("Variable name \"", initializeFromVariable,
                               "\" does not end with property name \"",
                               PropertyName, "\""));
      return false;
    }
    if (initializeFromVariable == PropertyName) {
      status.SetError(cmStrCat(
        "Variable name must have a non-empty prefix before property name \"",
        PropertyName, "\""));
      return false;
    }
  }

  // Make sure the variable is not reserved.
  static constexpr const char* reservedPrefixes[] = {
    "CMAKE_",
    "_CMAKE_",
  };
  if (std::any_of(std::begin(reservedPrefixes), std::end(reservedPrefixes),
                  [&initializeFromVariable](const char* prefix) {
                    return cmHasPrefix(initializeFromVariable, prefix);
                  })) {
    status.SetError(
      cmStrCat("variable name \"", initializeFromVariable, "\" is reserved"));
    return false;
  }

  // Actually define the property.
  status.GetMakefile().GetState()->DefineProperty(
    PropertyName, scope, cmJoin(BriefDocs, ""), cmJoin(FullDocs, ""),
    inherited, initializeFromVariable);

  return true;
}
