/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file LICENSE.rst 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 "cmStateSnapshot.h"
#include "cmStateTypes.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["CMakeDetermineVSServicePack"] = cmPolicies::CMP0196;
    DeprecatedModules["CMakeFindFrameworks"] = cmPolicies::CMP0173;
    DeprecatedModules["Dart"] = cmPolicies::CMP0145;
    DeprecatedModules["Documentation"] = cmPolicies::CMP0106;
    DeprecatedModules["FindBoost"] = cmPolicies::CMP0167;
    DeprecatedModules["FindCABLE"] = cmPolicies::CMP0191;
    DeprecatedModules["FindCUDA"] = cmPolicies::CMP0146;
    DeprecatedModules["FindDart"] = cmPolicies::CMP0145;
    DeprecatedModules["FindGCCXML"] = cmPolicies::CMP0188;
    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;
  }

  if (status.GetMakefile().GetStateSnapshot().GetUnwindState() ==
      cmStateEnums::UNWINDING) {
    status.SetError("called while already in an UNWIND state");
    return false;
  }

  bool optional = false;
  cm::PolicyScope policyScope = cm::PolicyScope::Local;
  cm::DiagnosticScope diagnosticScope = cm::DiagnosticScope::Local;
  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") {
      policyScope = cm::PolicyScope::None;
    } else if (args[i] == "NO_DIAGNOSTIC_SCOPE") {
      diagnosticScope = cm::DiagnosticScope::None;
    } 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 const readit = status.GetMakefile().ReadDependentFile(
    listFile, policyScope, diagnosticScope);

  // 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;
  }

  if (status.GetMakefile().GetStateSnapshot().GetUnwindState() ==
      cmStateEnums::UNWINDING) {

    if (status.GetMakefile().GetStateSnapshot().GetUnwindType() !=
        cmStateEnums::CAN_UNWIND) {
      std::string m = cmStrCat("requested file is attempting to unwind the "
                               "stack in an invalid context:\n ",
                               fname);
      status.SetError(m);
      cmSystemTools::SetFatalErrorOccurred();
      return false;
    }

    status.SetReturnInvoked();
  }

  return true;
}
