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

#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmValue.h"

// cmOptionCommand
bool cmOptionCommand(std::vector<std::string> const& args,
                     cmExecutionStatus& status)
{
  bool const argError = (args.size() < 2) || (args.size() > 3);
  if (argError) {
    std::string m = cmStrCat("called with incorrect number of arguments: ",
                             cmJoin(args, " "));
    status.SetError(m);
    return false;
  }

  // Determine the state of the option policy
  bool checkAndWarn = false;
  {
    auto policyStatus =
      status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0077);
    auto const& existsBeforeSet =
      status.GetMakefile().GetStateSnapshot().GetDefinition(args[0]);
    switch (policyStatus) {
      case cmPolicies::WARN:
        checkAndWarn = (existsBeforeSet != nullptr);
        CM_FALLTHROUGH;
      case cmPolicies::OLD:
        // OLD behavior does not warn.
        break;
      case cmPolicies::NEW: {
        // See if a local variable with this name already exists.
        // If so we ignore the option command.
        if (existsBeforeSet) {
          return true;
        }
      } break;
    }
  }

  // See if a cache variable with this name already exists
  // If so just make sure the doc state is correct
  cmState* state = status.GetMakefile().GetState();
  cmValue existingValue = state->GetCacheEntryValue(args[0]);
  if (existingValue &&
      (state->GetCacheEntryType(args[0]) != cmStateEnums::UNINITIALIZED)) {
    state->SetCacheEntryProperty(args[0], "HELPSTRING", args[1]);
    return true;
  }

  // Nothing in the cache so add it
  std::string initialValue = existingValue ? *existingValue : "Off";
  if (args.size() == 3) {
    initialValue = args[2];
  }
  bool init = cmIsOn(initialValue);
  status.GetMakefile().AddCacheDefinition(args[0], init ? "ON" : "OFF",
                                          args[1], cmStateEnums::BOOL);
  if (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0077) !=
        cmPolicies::NEW &&
      status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0126) ==
        cmPolicies::NEW) {
    // if there was a definition then remove it
    status.GetMakefile().GetStateSnapshot().RemoveDefinition(args[0]);
  }

  if (checkAndWarn) {
    auto const& existsAfterSet =
      status.GetMakefile().GetStateSnapshot().GetDefinition(args[0]);
    if (!existsAfterSet) {
      status.GetMakefile().IssueMessage(
        MessageType::AUTHOR_WARNING,
        cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0077),
                 "\n"
                 "For compatibility with older versions of CMake, option "
                 "is clearing the normal variable '",
                 args[0], "'."));
    }
  }
  return true;
}
