#include "cmPolicies.h"

#include "cmAlgorithms.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmSystemTools.h"
#include "cmVersion.h"

#include <assert.h>
#include <ctype.h>
#include <sstream>
#include <stdio.h>
#include <string.h>
#include <vector>

static bool stringToId(const char* input, cmPolicies::PolicyID& pid)
{
  assert(input);
  if (strlen(input) != 7) {
    return false;
  }
  if (!cmHasLiteralPrefix(input, "CMP")) {
    return false;
  }
  if (cmHasLiteralSuffix(input, "0000")) {
    pid = cmPolicies::CMP0000;
    return true;
  }
  for (int i = 3; i < 7; ++i) {
    if (!isdigit(*(input + i))) {
      return false;
    }
  }
  long id;
  if (!cmSystemTools::StringToLong(input + 3, &id)) {
    return false;
  }
  if (id >= cmPolicies::CMPCOUNT) {
    return false;
  }
  pid = cmPolicies::PolicyID(id);
  return true;
}

#define CM_SELECT_ID_VERSION(F, A1, A2, A3, A4, A5, A6) F(A1, A3, A4, A5)
#define CM_FOR_EACH_POLICY_ID_VERSION(POLICY)                                 \
  CM_FOR_EACH_POLICY_TABLE(POLICY, CM_SELECT_ID_VERSION)

#define CM_SELECT_ID_DOC(F, A1, A2, A3, A4, A5, A6) F(A1, A2)
#define CM_FOR_EACH_POLICY_ID_DOC(POLICY)                                     \
  CM_FOR_EACH_POLICY_TABLE(POLICY, CM_SELECT_ID_DOC)

static const char* idToString(cmPolicies::PolicyID id)
{
  switch (id) {
#define POLICY_CASE(ID)                                                       \
  case cmPolicies::ID:                                                        \
    return #ID;
    CM_FOR_EACH_POLICY_ID(POLICY_CASE)
#undef POLICY_CASE
    case cmPolicies::CMPCOUNT:
      return nullptr;
  }
  return nullptr;
}

static const char* idToVersion(cmPolicies::PolicyID id)
{
  switch (id) {
#define POLICY_CASE(ID, V_MAJOR, V_MINOR, V_PATCH)                            \
  case cmPolicies::ID:                                                        \
    return #V_MAJOR "." #V_MINOR "." #V_PATCH;
    CM_FOR_EACH_POLICY_ID_VERSION(POLICY_CASE)
#undef POLICY_CASE
    case cmPolicies::CMPCOUNT:
      return nullptr;
  }
  return nullptr;
}

static bool isPolicyNewerThan(cmPolicies::PolicyID id, unsigned int majorV,
                              unsigned int minorV, unsigned int patchV)
{
  switch (id) {
#define POLICY_CASE(ID, V_MAJOR, V_MINOR, V_PATCH)                            \
  case cmPolicies::ID:                                                        \
    return (majorV < (V_MAJOR) ||                                             \
            (majorV == (V_MAJOR) && minorV + 1 < (V_MINOR) + 1) ||            \
            (majorV == (V_MAJOR) && minorV == (V_MINOR) &&                    \
             patchV + 1 < (V_PATCH) + 1));
    CM_FOR_EACH_POLICY_ID_VERSION(POLICY_CASE)
#undef POLICY_CASE
    case cmPolicies::CMPCOUNT:
      return false;
  }
  return false;
}

const char* idToShortDescription(cmPolicies::PolicyID id)
{
  switch (id) {
#define POLICY_CASE(ID, SHORT_DESCRIPTION)                                    \
  case cmPolicies::ID:                                                        \
    return SHORT_DESCRIPTION;
    CM_FOR_EACH_POLICY_ID_DOC(POLICY_CASE)
#undef POLICY_CASE
    case cmPolicies::CMPCOUNT:
      return nullptr;
  }
  return nullptr;
}

static void DiagnoseAncientPolicies(
  std::vector<cmPolicies::PolicyID> const& ancient, unsigned int majorVer,
  unsigned int minorVer, unsigned int patchVer, cmMakefile* mf)
{
  std::ostringstream e;
  e << "The project requests behavior compatible with CMake version \""
    << majorVer << "." << minorVer << "." << patchVer
    << "\", which requires the OLD behavior for some policies:\n";
  for (cmPolicies::PolicyID i : ancient) {
    e << "  " << idToString(i) << ": " << idToShortDescription(i) << "\n";
  }
  e << "However, this version of CMake no longer supports the OLD "
    << "behavior for these policies.  "
    << "Please either update your CMakeLists.txt files to conform to "
    << "the new behavior or use an older version of CMake that still "
    << "supports the old behavior.";
  mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
}

static bool GetPolicyDefault(cmMakefile* mf, std::string const& policy,
                             cmPolicies::PolicyStatus* defaultSetting)
{
  std::string defaultVar = "CMAKE_POLICY_DEFAULT_" + policy;
  std::string const& defaultValue = mf->GetSafeDefinition(defaultVar);
  if (defaultValue == "NEW") {
    *defaultSetting = cmPolicies::NEW;
  } else if (defaultValue == "OLD") {
    *defaultSetting = cmPolicies::OLD;
  } else if (defaultValue.empty()) {
    *defaultSetting = cmPolicies::WARN;
  } else {
    std::ostringstream e;
    e << defaultVar << " has value \"" << defaultValue
      << R"(" but must be "OLD", "NEW", or "" (empty).)";
    mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
    return false;
  }

  return true;
}

bool cmPolicies::ApplyPolicyVersion(cmMakefile* mf,
                                    std::string const& version_min,
                                    std::string const& version_max)
{
  // Parse components of the minimum version.
  unsigned int minMajor = 2;
  unsigned int minMinor = 0;
  unsigned int minPatch = 0;
  unsigned int minTweak = 0;
  if (sscanf(version_min.c_str(), "%u.%u.%u.%u", &minMajor, &minMinor,
             &minPatch, &minTweak) < 2) {
    std::ostringstream e;
    e << "Invalid policy version value \"" << version_min << "\".  "
      << "A numeric major.minor[.patch[.tweak]] must be given.";
    mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
    return false;
  }

  // it is an error if the policy version is less than 2.4
  if (minMajor < 2 || (minMajor == 2 && minMinor < 4)) {
    mf->IssueMessage(
      MessageType::FATAL_ERROR,
      "Compatibility with CMake < 2.4 is not supported by CMake >= 3.0.  "
      "For compatibility with older versions please use any CMake 2.8.x "
      "release or lower.");
    return false;
  }

  // It is an error if the policy version is greater than the running
  // CMake.
  if (minMajor > cmVersion::GetMajorVersion() ||
      (minMajor == cmVersion::GetMajorVersion() &&
       minMinor > cmVersion::GetMinorVersion()) ||
      (minMajor == cmVersion::GetMajorVersion() &&
       minMinor == cmVersion::GetMinorVersion() &&
       minPatch > cmVersion::GetPatchVersion()) ||
      (minMajor == cmVersion::GetMajorVersion() &&
       minMinor == cmVersion::GetMinorVersion() &&
       minPatch == cmVersion::GetPatchVersion() &&
       minTweak > cmVersion::GetTweakVersion())) {
    std::ostringstream e;
    e << "An attempt was made to set the policy version of CMake to \""
      << version_min << "\" which is greater than this version of CMake.  "
      << "This is not allowed because the greater version may have new "
      << "policies not known to this CMake.  "
      << "You may need a newer CMake version to build this project.";
    mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
    return false;
  }

  unsigned int polMajor = minMajor;
  unsigned int polMinor = minMinor;
  unsigned int polPatch = minPatch;

  if (!version_max.empty()) {
    // Parse components of the maximum version.
    unsigned int maxMajor = 0;
    unsigned int maxMinor = 0;
    unsigned int maxPatch = 0;
    unsigned int maxTweak = 0;
    if (sscanf(version_max.c_str(), "%u.%u.%u.%u", &maxMajor, &maxMinor,
               &maxPatch, &maxTweak) < 2) {
      std::ostringstream e;
      e << "Invalid policy max version value \"" << version_max << "\".  "
        << "A numeric major.minor[.patch[.tweak]] must be given.";
      mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
      return false;
    }

    // It is an error if the min version is greater than the max version.
    if (minMajor > maxMajor || (minMajor == maxMajor && minMinor > maxMinor) ||
        (minMajor == maxMajor && minMinor == maxMinor &&
         minPatch > maxPatch) ||
        (minMajor == maxMajor && minMinor == maxMinor &&
         minPatch == maxPatch && minTweak > maxTweak)) {
      std::ostringstream e;
      e << "Policy VERSION range \"" << version_min << "..." << version_max
        << "\""
        << " specifies a larger minimum than maximum.";
      mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
      return false;
    }

    // Use the max version as the policy version.
    polMajor = maxMajor;
    polMinor = maxMinor;
    polPatch = maxPatch;
  }

  return cmPolicies::ApplyPolicyVersion(mf, polMajor, polMinor, polPatch);
}

bool cmPolicies::ApplyPolicyVersion(cmMakefile* mf, unsigned int majorVer,
                                    unsigned int minorVer,
                                    unsigned int patchVer)
{
  // now loop over all the policies and set them as appropriate
  std::vector<cmPolicies::PolicyID> ancientPolicies;
  for (PolicyID pid = cmPolicies::CMP0000; pid != cmPolicies::CMPCOUNT;
       pid = PolicyID(pid + 1)) {
    if (isPolicyNewerThan(pid, majorVer, minorVer, patchVer)) {
      if (cmPolicies::GetPolicyStatus(pid) == cmPolicies::REQUIRED_ALWAYS) {
        ancientPolicies.push_back(pid);
      } else {
        cmPolicies::PolicyStatus status = cmPolicies::WARN;
        if (!GetPolicyDefault(mf, idToString(pid), &status) ||
            !mf->SetPolicy(pid, status)) {
          return false;
        }
        if (pid == cmPolicies::CMP0001 &&
            (status == cmPolicies::WARN || status == cmPolicies::OLD)) {
          if (!(mf->GetState()->GetInitializedCacheValue(
                "CMAKE_BACKWARDS_COMPATIBILITY"))) {
            // Set it to 2.4 because that is the last version where the
            // variable had meaning.
            mf->AddCacheDefinition(
              "CMAKE_BACKWARDS_COMPATIBILITY", "2.4",
              "For backwards compatibility, what version of CMake "
              "commands and "
              "syntax should this version of CMake try to support.",
              cmStateEnums::STRING);
          }
        }
      }
    } else {
      if (!mf->SetPolicy(pid, cmPolicies::NEW)) {
        return false;
      }
    }
  }

  // Make sure the project does not use any ancient policies.
  if (!ancientPolicies.empty()) {
    DiagnoseAncientPolicies(ancientPolicies, majorVer, minorVer, patchVer, mf);
    cmSystemTools::SetFatalErrorOccured();
    return false;
  }

  return true;
}

bool cmPolicies::GetPolicyID(const char* id, cmPolicies::PolicyID& pid)
{
  return stringToId(id, pid);
}

//! return a warning string for a given policy
std::string cmPolicies::GetPolicyWarning(cmPolicies::PolicyID id)
{
  std::ostringstream msg;
  msg << "Policy " << idToString(id)
      << " is not set: "
         ""
      << idToShortDescription(id)
      << "  "
         "Run \"cmake --help-policy "
      << idToString(id)
      << "\" for "
         "policy details.  "
         "Use the cmake_policy command to set the policy "
         "and suppress this warning.";
  return msg.str();
}

std::string cmPolicies::GetPolicyDeprecatedWarning(cmPolicies::PolicyID id)
{
  std::ostringstream msg;
  /* clang-format off */
  msg <<
    "The OLD behavior for policy " << idToString(id) << " "
    "will be removed from a future version of CMake.\n"
    "The cmake-policies(7) manual explains that the OLD behaviors of all "
    "policies are deprecated and that a policy should be set to OLD only "
    "under specific short-term circumstances.  Projects should be ported "
    "to the NEW behavior and not rely on setting a policy to OLD."
    ;
  /* clang-format on */
  return msg.str();
}

//! return an error string for when a required policy is unspecified
std::string cmPolicies::GetRequiredPolicyError(cmPolicies::PolicyID id)
{
  std::ostringstream error;
  error << "Policy " << idToString(id)
        << " is not set to NEW: "
           ""
        << idToShortDescription(id)
        << "  "
           "Run \"cmake --help-policy "
        << idToString(id)
        << "\" for "
           "policy details.  "
           "CMake now requires this policy to be set to NEW by the project.  "
           "The policy may be set explicitly using the code\n"
           "  cmake_policy(SET "
        << idToString(id)
        << " NEW)\n"
           "or by upgrading all policies with the code\n"
           "  cmake_policy(VERSION "
        << idToVersion(id)
        << ") # or later\n"
           "Run \"cmake --help-command cmake_policy\" for more information.";
  return error.str();
}

//! Get the default status for a policy
cmPolicies::PolicyStatus cmPolicies::GetPolicyStatus(
  cmPolicies::PolicyID /*unused*/)
{
  return cmPolicies::WARN;
}

std::string cmPolicies::GetRequiredAlwaysPolicyError(cmPolicies::PolicyID id)
{
  std::string pid = idToString(id);
  std::ostringstream e;
  e << "Policy " << pid << " may not be set to OLD behavior because this "
    << "version of CMake no longer supports it.  "
    << "The policy was introduced in "
    << "CMake version " << idToVersion(id)
    << ", and use of NEW behavior is now required."
    << "\n"
    << "Please either update your CMakeLists.txt files to conform to "
    << "the new behavior or use an older version of CMake that still "
    << "supports the old behavior.  "
    << "Run cmake --help-policy " << pid << " for more information.";
  return e.str();
}

cmPolicies::PolicyStatus cmPolicies::PolicyMap::Get(
  cmPolicies::PolicyID id) const
{
  PolicyStatus status = cmPolicies::WARN;

  if (this->Status[(POLICY_STATUS_COUNT * id) + OLD]) {
    status = cmPolicies::OLD;
  } else if (this->Status[(POLICY_STATUS_COUNT * id) + NEW]) {
    status = cmPolicies::NEW;
  }
  return status;
}

void cmPolicies::PolicyMap::Set(cmPolicies::PolicyID id,
                                cmPolicies::PolicyStatus status)
{
  this->Status[(POLICY_STATUS_COUNT * id) + OLD] = (status == OLD);
  this->Status[(POLICY_STATUS_COUNT * id) + WARN] = (status == WARN);
  this->Status[(POLICY_STATUS_COUNT * id) + NEW] = (status == NEW);
}

bool cmPolicies::PolicyMap::IsDefined(cmPolicies::PolicyID id) const
{
  return this->Status[(POLICY_STATUS_COUNT * id) + OLD] ||
    this->Status[(POLICY_STATUS_COUNT * id) + WARN] ||
    this->Status[(POLICY_STATUS_COUNT * id) + NEW];
}

bool cmPolicies::PolicyMap::IsEmpty() const
{
  return this->Status.none();
}
