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

#include <sstream>

#include "cmAlgorithms.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
#include "cmSystemTools.h"

class cmExecutionStatus;

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

  // Determine the state of the option policy
  bool checkAndWarn = false;
  {
    auto status = this->Makefile->GetPolicyStatus(cmPolicies::CMP0077);
    const auto* existsBeforeSet =
      this->Makefile->GetStateSnapshot().GetDefinition(args[0]);
    switch (status) {
      case cmPolicies::WARN:
        checkAndWarn = (existsBeforeSet != nullptr);
        break;
      case cmPolicies::OLD:
        // OLD behavior does not warn.
        break;
      case cmPolicies::REQUIRED_ALWAYS:
      case cmPolicies::REQUIRED_IF_USED:
      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 = this->Makefile->GetState();
  const char* 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 = cmSystemTools::IsOn(initialValue);
  this->Makefile->AddCacheDefinition(args[0], init ? "ON" : "OFF",
                                     args[1].c_str(), cmStateEnums::BOOL);

  if (checkAndWarn) {
    const auto* existsAfterSet =
      this->Makefile->GetStateSnapshot().GetDefinition(args[0]);
    if (!existsAfterSet) {
      std::ostringstream w;
      w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0077)
        << "\n"
           "For compatibility with older versions of CMake, option "
           "is clearing the normal variable '"
        << args[0] << "'.";
      this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
    }
  }
  return true;
}
