/* 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 "cmArgumentParserTypes.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;
  ArgumentParser::NonEmpty<std::vector<std::string>> BriefDocs;
  ArgumentParser::NonEmpty<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 (PropertyName.find('_') == std::string::npos) {
      status.SetError(cmStrCat("Property name \"", PropertyName,
                               "\" defined with INITIALIZE_FROM_VARIABLE does "
                               "not contain underscore"));
      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;
}
