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

#include "cmsys/RegularExpression.hxx"
#include <functional>
#include <sstream>
#include <stdio.h>

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

class cmExecutionStatus;

// cmProjectCommand
bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
                                   cmExecutionStatus&)
{
  if (args.empty()) {
    this->SetError("PROJECT called with incorrect number of arguments");
    return false;
  }

  if (!this->IncludeByVariable("CMAKE_PROJECT_INCLUDE_BEFORE")) {
    return false;
  }

  std::string const& projectName = args[0];

  this->Makefile->SetProjectName(projectName);

  std::string bindir = projectName;
  bindir += "_BINARY_DIR";
  std::string srcdir = projectName;
  srcdir += "_SOURCE_DIR";

  this->Makefile->AddCacheDefinition(
    bindir, this->Makefile->GetCurrentBinaryDirectory().c_str(),
    "Value Computed by CMake", cmStateEnums::STATIC);
  this->Makefile->AddCacheDefinition(
    srcdir, this->Makefile->GetCurrentSourceDirectory().c_str(),
    "Value Computed by CMake", cmStateEnums::STATIC);

  bindir = "PROJECT_BINARY_DIR";
  srcdir = "PROJECT_SOURCE_DIR";

  this->Makefile->AddDefinition(
    bindir, this->Makefile->GetCurrentBinaryDirectory().c_str());
  this->Makefile->AddDefinition(
    srcdir, this->Makefile->GetCurrentSourceDirectory().c_str());

  this->Makefile->AddDefinition("PROJECT_NAME", projectName.c_str());

  // Set the CMAKE_PROJECT_NAME variable to be the highest-level
  // project name in the tree. If there are two project commands
  // in the same CMakeLists.txt file, and it is the top level
  // CMakeLists.txt file, then go with the last one, so that
  // CMAKE_PROJECT_NAME will match PROJECT_NAME, and cmake --build
  // will work.
  if (!this->Makefile->GetDefinition("CMAKE_PROJECT_NAME") ||
      (this->Makefile->IsRootMakefile())) {
    this->Makefile->AddDefinition("CMAKE_PROJECT_NAME", projectName.c_str());
    this->Makefile->AddCacheDefinition(
      "CMAKE_PROJECT_NAME", projectName.c_str(), "Value Computed by CMake",
      cmStateEnums::STATIC);
  }

  bool haveVersion = false;
  bool haveLanguages = false;
  bool haveDescription = false;
  bool haveHomepage = false;
  bool injectedProjectCommand = false;
  std::string version;
  std::string description;
  std::string homepage;
  std::vector<std::string> languages;
  std::function<void()> missedValueReporter;
  auto resetReporter = [&missedValueReporter]() {
    missedValueReporter = std::function<void()>();
  };
  enum Doing
  {
    DoingDescription,
    DoingHomepage,
    DoingLanguages,
    DoingVersion
  };
  Doing doing = DoingLanguages;
  for (size_t i = 1; i < args.size(); ++i) {
    if (args[i] == "LANGUAGES") {
      if (haveLanguages) {
        this->Makefile->IssueMessage(
          MessageType::FATAL_ERROR,
          "LANGUAGES may be specified at most once.");
        cmSystemTools::SetFatalErrorOccured();
        return true;
      }
      haveLanguages = true;
      if (missedValueReporter) {
        missedValueReporter();
      }
      doing = DoingLanguages;
      if (!languages.empty()) {
        std::string msg =
          "the following parameters must be specified after LANGUAGES "
          "keyword: ";
        msg += cmJoin(languages, ", ");
        msg += '.';
        this->Makefile->IssueMessage(MessageType::WARNING, msg);
      }
    } else if (args[i] == "VERSION") {
      if (haveVersion) {
        this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
                                     "VERSION may be specified at most once.");
        cmSystemTools::SetFatalErrorOccured();
        return true;
      }
      haveVersion = true;
      if (missedValueReporter) {
        missedValueReporter();
      }
      doing = DoingVersion;
      missedValueReporter = [this, &resetReporter]() {
        this->Makefile->IssueMessage(
          MessageType::WARNING,
          "VERSION keyword not followed by a value or was followed by a "
          "value that expanded to nothing.");
        resetReporter();
      };
    } else if (args[i] == "DESCRIPTION") {
      if (haveDescription) {
        this->Makefile->IssueMessage(
          MessageType::FATAL_ERROR,
          "DESCRIPTION may be specified at most once.");
        cmSystemTools::SetFatalErrorOccured();
        return true;
      }
      haveDescription = true;
      if (missedValueReporter) {
        missedValueReporter();
      }
      doing = DoingDescription;
      missedValueReporter = [this, &resetReporter]() {
        this->Makefile->IssueMessage(
          MessageType::WARNING,
          "DESCRIPTION keyword not followed by a value or was followed "
          "by a value that expanded to nothing.");
        resetReporter();
      };
    } else if (args[i] == "HOMEPAGE_URL") {
      if (haveHomepage) {
        this->Makefile->IssueMessage(
          MessageType::FATAL_ERROR,
          "HOMEPAGE_URL may be specified at most once.");
        cmSystemTools::SetFatalErrorOccured();
        return true;
      }
      haveHomepage = true;
      doing = DoingHomepage;
      missedValueReporter = [this, &resetReporter]() {
        this->Makefile->IssueMessage(
          MessageType::WARNING,
          "HOMEPAGE_URL keyword not followed by a value or was followed "
          "by a value that expanded to nothing.");
        resetReporter();
      };
    } else if (i == 1 && args[i] == "__CMAKE_INJECTED_PROJECT_COMMAND__") {
      injectedProjectCommand = true;
    } else if (doing == DoingVersion) {
      doing = DoingLanguages;
      version = args[i];
      resetReporter();
    } else if (doing == DoingDescription) {
      doing = DoingLanguages;
      description = args[i];
      resetReporter();
    } else if (doing == DoingHomepage) {
      doing = DoingLanguages;
      homepage = args[i];
      resetReporter();
    } else // doing == DoingLanguages
    {
      languages.push_back(args[i]);
    }
  }

  if (missedValueReporter) {
    missedValueReporter();
  }

  if ((haveVersion || haveDescription || haveHomepage) && !haveLanguages &&
      !languages.empty()) {
    this->Makefile->IssueMessage(
      MessageType::FATAL_ERROR,
      "project with VERSION, DESCRIPTION or HOMEPAGE_URL must "
      "use LANGUAGES before language names.");
    cmSystemTools::SetFatalErrorOccured();
    return true;
  }
  if (haveLanguages && languages.empty()) {
    languages.emplace_back("NONE");
  }

  cmPolicies::PolicyStatus cmp0048 =
    this->Makefile->GetPolicyStatus(cmPolicies::CMP0048);
  if (haveVersion) {
    // Set project VERSION variables to given values
    if (cmp0048 == cmPolicies::OLD || cmp0048 == cmPolicies::WARN) {
      this->Makefile->IssueMessage(
        MessageType::FATAL_ERROR,
        "VERSION not allowed unless CMP0048 is set to NEW");
      cmSystemTools::SetFatalErrorOccured();
      return true;
    }

    cmsys::RegularExpression vx(
      R"(^([0-9]+(\.[0-9]+(\.[0-9]+(\.[0-9]+)?)?)?)?$)");
    if (!vx.find(version)) {
      std::string e = "VERSION \"" + version + "\" format invalid.";
      this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e);
      cmSystemTools::SetFatalErrorOccured();
      return true;
    }

    std::string vs;
    const char* sep = "";
    char vb[4][64];
    unsigned int v[4] = { 0, 0, 0, 0 };
    int vc =
      sscanf(version.c_str(), "%u.%u.%u.%u", &v[0], &v[1], &v[2], &v[3]);
    for (int i = 0; i < 4; ++i) {
      if (i < vc) {
        sprintf(vb[i], "%u", v[i]);
        vs += sep;
        vs += vb[i];
        sep = ".";
      } else {
        vb[i][0] = 0;
      }
    }

    std::string vv;
    vv = projectName + "_VERSION";
    this->Makefile->AddDefinition("PROJECT_VERSION", vs.c_str());
    this->Makefile->AddDefinition(vv, vs.c_str());
    vv = projectName + "_VERSION_MAJOR";
    this->Makefile->AddDefinition("PROJECT_VERSION_MAJOR", vb[0]);
    this->Makefile->AddDefinition(vv, vb[0]);
    vv = projectName + "_VERSION_MINOR";
    this->Makefile->AddDefinition("PROJECT_VERSION_MINOR", vb[1]);
    this->Makefile->AddDefinition(vv, vb[1]);
    vv = projectName + "_VERSION_PATCH";
    this->Makefile->AddDefinition("PROJECT_VERSION_PATCH", vb[2]);
    this->Makefile->AddDefinition(vv, vb[2]);
    vv = projectName + "_VERSION_TWEAK";
    this->Makefile->AddDefinition("PROJECT_VERSION_TWEAK", vb[3]);
    this->Makefile->AddDefinition(vv, vb[3]);
    // Also, try set top level variables
    TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION", vs.c_str());
    TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_MAJOR", vb[0]);
    TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_MINOR", vb[1]);
    TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_PATCH", vb[2]);
    TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_TWEAK", vb[3]);
  } else if (cmp0048 != cmPolicies::OLD) {
    // Set project VERSION variables to empty
    std::vector<std::string> vv;
    vv.emplace_back("PROJECT_VERSION");
    vv.emplace_back("PROJECT_VERSION_MAJOR");
    vv.emplace_back("PROJECT_VERSION_MINOR");
    vv.emplace_back("PROJECT_VERSION_PATCH");
    vv.emplace_back("PROJECT_VERSION_TWEAK");
    vv.push_back(projectName + "_VERSION");
    vv.push_back(projectName + "_VERSION_MAJOR");
    vv.push_back(projectName + "_VERSION_MINOR");
    vv.push_back(projectName + "_VERSION_PATCH");
    vv.push_back(projectName + "_VERSION_TWEAK");
    if (this->Makefile->IsRootMakefile()) {
      vv.emplace_back("CMAKE_PROJECT_VERSION");
      vv.emplace_back("CMAKE_PROJECT_VERSION_MAJOR");
      vv.emplace_back("CMAKE_PROJECT_VERSION_MINOR");
      vv.emplace_back("CMAKE_PROJECT_VERSION_PATCH");
      vv.emplace_back("CMAKE_PROJECT_VERSION_TWEAK");
    }
    std::string vw;
    for (std::string const& i : vv) {
      const char* v = this->Makefile->GetDefinition(i);
      if (v && *v) {
        if (cmp0048 == cmPolicies::WARN) {
          if (!injectedProjectCommand) {
            vw += "\n  ";
            vw += i;
          }
        } else {
          this->Makefile->AddDefinition(i, "");
        }
      }
    }
    if (!vw.empty()) {
      std::ostringstream w;
      w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0048)
        << "\nThe following variable(s) would be set to empty:" << vw;
      this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
    }
  }

  this->Makefile->AddDefinition("PROJECT_DESCRIPTION", description.c_str());
  this->Makefile->AddDefinition(projectName + "_DESCRIPTION",
                                description.c_str());
  TopLevelCMakeVarCondSet("CMAKE_PROJECT_DESCRIPTION", description.c_str());

  this->Makefile->AddDefinition("PROJECT_HOMEPAGE_URL", homepage.c_str());
  this->Makefile->AddDefinition(projectName + "_HOMEPAGE_URL",
                                homepage.c_str());
  TopLevelCMakeVarCondSet("CMAKE_PROJECT_HOMEPAGE_URL", homepage.c_str());

  if (languages.empty()) {
    // if no language is specified do c and c++
    languages.emplace_back("C");
    languages.emplace_back("CXX");
  }
  this->Makefile->EnableLanguage(languages, false);

  if (!this->IncludeByVariable("CMAKE_PROJECT_INCLUDE")) {
    return false;
  }

  if (!this->IncludeByVariable("CMAKE_PROJECT_" + projectName + "_INCLUDE")) {
    return false;
  }

  return true;
}

bool cmProjectCommand::IncludeByVariable(const std::string& variable)
{
  const char* include = this->Makefile->GetDefinition(variable);
  if (!include) {
    return true;
  }

  const bool readit = this->Makefile->ReadDependentFile(include);
  if (readit) {
    return true;
  }

  if (cmSystemTools::GetFatalErrorOccured()) {
    return true;
  }

  std::string m = "could not find file:\n"
                  "  ";
  m += include;
  this->SetError(m);
  return false;
}

void cmProjectCommand::TopLevelCMakeVarCondSet(const char* const name,
                                               const char* const value)
{
  // Set the CMAKE_PROJECT_XXX variable to be the highest-level
  // project name in the tree. If there are two project commands
  // in the same CMakeLists.txt file, and it is the top level
  // CMakeLists.txt file, then go with the last one.
  if (!this->Makefile->GetDefinition(name) ||
      (this->Makefile->IsRootMakefile())) {
    this->Makefile->AddDefinition(name, value);
    this->Makefile->AddCacheDefinition(name, value, "Value Computed by CMake",
                                       cmStateEnums::STATIC);
  }
}
