#include "cmPolicies.h"
#include "cmake.h"
#include "cmMakefile.h"
#include "cmVersion.h"
#include "cmVersionMacros.h"
#include "cmAlgorithms.h"
#include <map>
#include <set>
#include <queue>
#include <assert.h>

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 0;
    }
  return 0;
}

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 0;
    }
  return 0;
}

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 0;
    }
  return 0;
}

//----------------------------------------------------------------------------
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(std::vector<cmPolicies::PolicyID>::const_iterator
        i = ancient.begin(); i != ancient.end(); ++i)
    {
    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(cmake::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 defaultValue = mf->GetSafeDefinition(defaultVar);
  if(defaultValue == "NEW")
    {
    *defaultSetting = cmPolicies::NEW;
    }
  else if(defaultValue == "OLD")
    {
    *defaultSetting = cmPolicies::OLD;
    }
  else if(defaultValue == "")
    {
    *defaultSetting = cmPolicies::WARN;
    }
  else
    {
    std::ostringstream e;
    e << defaultVar << " has value \"" << defaultValue
      << "\" but must be \"OLD\", \"NEW\", or \"\" (empty).";
    mf->IssueMessage(cmake::FATAL_ERROR, e.str());
    return false;
    }

  return true;
}

//----------------------------------------------------------------------------
bool cmPolicies::ApplyPolicyVersion(cmMakefile *mf,
                                    const char *version)
{
  std::string ver = "2.4.0";

  if (version && strlen(version) > 0)
    {
    ver = version;
    }

  unsigned int majorVer = 2;
  unsigned int minorVer = 0;
  unsigned int patchVer = 0;
  unsigned int tweakVer = 0;

  // parse the string
  if(sscanf(ver.c_str(), "%u.%u.%u.%u",
            &majorVer, &minorVer, &patchVer, &tweakVer) < 2)
    {
    std::ostringstream e;
    e << "Invalid policy version value \"" << ver << "\".  "
      << "A numeric major.minor[.patch[.tweak]] must be given.";
    mf->IssueMessage(cmake::FATAL_ERROR, e.str());
    return false;
    }

  // it is an error if the policy version is less than 2.4
  if (majorVer < 2 || (majorVer == 2 && minorVer < 4))
    {
    mf->IssueMessage(cmake::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 (majorVer > cmVersion::GetMajorVersion() ||
      (majorVer == cmVersion::GetMajorVersion() &&
       minorVer > cmVersion::GetMinorVersion()) ||
      (majorVer == cmVersion::GetMajorVersion() &&
       minorVer == cmVersion::GetMinorVersion() &&
       patchVer > cmVersion::GetPatchVersion()) ||
      (majorVer == cmVersion::GetMajorVersion() &&
       minorVer == cmVersion::GetMinorVersion() &&
       patchVer == cmVersion::GetPatchVersion() &&
       tweakVer > cmVersion::GetTweakVersion()))
    {
    std::ostringstream e;
    e << "An attempt was made to set the policy version of CMake to \""
      << version << "\" 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(cmake::FATAL_ERROR, e.str());
    return false;
    }

  // 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.",
               cmState::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();
}


///! 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)
{
  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();
}
