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

#include <map>
#include <utility>

#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"

// cmIncludeCommand
bool cmIncludeCommand(std::vector<std::string> const& args,
                      cmExecutionStatus& status)
{
  static std::map<std::string, cmPolicies::PolicyID> DeprecatedModules;
  if (DeprecatedModules.empty()) {
    DeprecatedModules["CMakeFindFrameworks"] = cmPolicies::CMP0173;
    DeprecatedModules["Dart"] = cmPolicies::CMP0145;
    DeprecatedModules["Documentation"] = cmPolicies::CMP0106;
    DeprecatedModules["FindBoost"] = cmPolicies::CMP0167;
    DeprecatedModules["FindCUDA"] = cmPolicies::CMP0146;
    DeprecatedModules["FindDart"] = cmPolicies::CMP0145;
    DeprecatedModules["FindPythonInterp"] = cmPolicies::CMP0148;
    DeprecatedModules["FindPythonLibs"] = cmPolicies::CMP0148;
    DeprecatedModules["WriteCompilerDetectionHeader"] = cmPolicies::CMP0120;
  }

  if (args.empty() || args.size() > 4) {
    status.SetError("called with wrong number of arguments.  "
                    "include() only takes one file.");
    return false;
  }
  bool optional = false;
  bool noPolicyScope = false;
  std::string fname = args[0];
  std::string resultVarName;

  for (unsigned int i = 1; i < args.size(); i++) {
    if (args[i] == "OPTIONAL") {
      if (optional) {
        status.SetError("called with invalid arguments: OPTIONAL used twice");
        return false;
      }
      optional = true;
    } else if (args[i] == "RESULT_VARIABLE") {
      if (!resultVarName.empty()) {
        status.SetError("called with invalid arguments: "
                        "only one result variable allowed");
        return false;
      }
      if (++i < args.size()) {
        resultVarName = args[i];
      } else {
        status.SetError("called with no value for RESULT_VARIABLE.");
        return false;
      }
    } else if (args[i] == "NO_POLICY_SCOPE") {
      noPolicyScope = true;
    } else if (i > 1) // compat.: in previous cmake versions the second
                      // parameter was ignored if it wasn't "OPTIONAL"
    {
      std::string errorText =
        cmStrCat("called with invalid argument: ", args[i]);
      status.SetError(errorText);
      return false;
    }
  }

  if (fname.empty()) {
    status.GetMakefile().IssueMessage(
      MessageType::AUTHOR_WARNING,
      "include() given empty file name (ignored).");
    return true;
  }

  if (!cmSystemTools::FileIsFullPath(fname)) {
    bool system = false;
    // Not a path. Maybe module.
    std::string module = cmStrCat(fname, ".cmake");
    std::string mfile = status.GetMakefile().GetModulesFile(module, system);

    if (system) {
      auto ModulePolicy = DeprecatedModules.find(fname);
      if (ModulePolicy != DeprecatedModules.end()) {
        cmPolicies::PolicyStatus PolicyStatus =
          status.GetMakefile().GetPolicyStatus(ModulePolicy->second);
        switch (PolicyStatus) {
          case cmPolicies::WARN: {
            status.GetMakefile().IssueMessage(
              MessageType::AUTHOR_WARNING,
              cmStrCat(cmPolicies::GetPolicyWarning(ModulePolicy->second),
                       "\n"));
            CM_FALLTHROUGH;
          }
          case cmPolicies::OLD:
            break;
          case cmPolicies::NEW:
            mfile = "";
            break;
        }
      }
    }

    if (!mfile.empty()) {
      fname = mfile;
    }
  }

  std::string fname_abs = cmSystemTools::CollapseFullPath(
    fname, status.GetMakefile().GetCurrentSourceDirectory());

  cmGlobalGenerator* gg = status.GetMakefile().GetGlobalGenerator();
  if (gg->IsExportedTargetsFile(fname_abs)) {
    status.GetMakefile().IssueMessage(
      MessageType::FATAL_ERROR,
      cmStrCat(
        "The file\n  ", fname_abs,
        "\nwas generated by the export() "
        "command.  It may not be used as the argument to the "
        "include() command.  Use ALIAS targets instead to refer to targets "
        "by alternative names.\n"));
    return false;
  }

  std::string listFile = cmSystemTools::CollapseFullPath(
    fname, status.GetMakefile().GetCurrentSourceDirectory());

  bool const fileDoesnotExist = !cmSystemTools::FileExists(listFile);
  bool const fileIsDirectory = cmSystemTools::FileIsDirectory(listFile);
  if (fileDoesnotExist || fileIsDirectory) {
    if (!resultVarName.empty()) {
      status.GetMakefile().AddDefinition(resultVarName, "NOTFOUND");
    }
    if (optional) {
      return true;
    }
    if (fileDoesnotExist) {
      status.SetError(cmStrCat("could not find requested file:\n  ", fname));
      return false;
    }
    if (fileIsDirectory) {
      status.SetError(cmStrCat("requested file is a directory:\n  ", fname));
      return false;
    }
  }

  bool readit =
    status.GetMakefile().ReadDependentFile(listFile, noPolicyScope);

  // add the location of the included file if a result variable was given
  if (!resultVarName.empty()) {
    status.GetMakefile().AddDefinition(
      resultVarName, readit ? fname_abs.c_str() : "NOTFOUND");
  }

  if (!optional && !readit && !cmSystemTools::GetFatalErrorOccurred()) {
    std::string m = cmStrCat("could not load requested file:\n  ", fname);
    status.SetError(m);
    return false;
  }
  return true;
}
