/* 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 <sstream>

#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmPolicies.h"
#include "cmSystemTools.h"
#include "cmake.h"

class cmExecutionStatus;

// cmIncludeCommand
bool cmIncludeCommand::InitialPass(std::vector<std::string> const& args,
                                   cmExecutionStatus&)
{
  if (args.empty() || args.size() > 4) {
    this->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) {
        this->SetError("called with invalid arguments: OPTIONAL used twice");
        return false;
      }
      optional = true;
    } else if (args[i] == "RESULT_VARIABLE") {
      if (!resultVarName.empty()) {
        this->SetError("called with invalid arguments: "
                       "only one result variable allowed");
        return false;
      }
      if (++i < args.size()) {
        resultVarName = args[i];
      } else {
        this->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 = "called with invalid argument: ";
      errorText += args[i];
      this->SetError(errorText);
      return false;
    }
  }

  if (fname.empty()) {
    this->Makefile->IssueMessage(cmake::AUTHOR_WARNING,
                                 "include() given empty file name (ignored).");
    return true;
  }

  if (!cmSystemTools::FileIsFullPath(fname.c_str())) {
    // Not a path. Maybe module.
    std::string module = fname;
    module += ".cmake";
    std::string mfile = this->Makefile->GetModulesFile(module.c_str());
    if (!mfile.empty()) {
      fname = mfile;
    }
  }

  std::string fname_abs = cmSystemTools::CollapseFullPath(
    fname, this->Makefile->GetCurrentSourceDirectory());

  cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
  if (gg->IsExportedTargetsFile(fname_abs)) {
    const char* modal = CM_NULLPTR;
    std::ostringstream e;
    cmake::MessageType messageType = cmake::AUTHOR_WARNING;

    switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0024)) {
      case cmPolicies::WARN:
        e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0024) << "\n";
        modal = "should";
      case cmPolicies::OLD:
        break;
      case cmPolicies::REQUIRED_IF_USED:
      case cmPolicies::REQUIRED_ALWAYS:
      case cmPolicies::NEW:
        modal = "may";
        messageType = cmake::FATAL_ERROR;
    }
    if (modal) {
      e << "The file\n  " << fname_abs << "\nwas generated by the export() "
                                          "command.  It "
        << modal
        << " not be used as the argument to the "
           "include() command.  Use ALIAS targets instead to refer to targets "
           "by alternative names.\n";
      this->Makefile->IssueMessage(messageType, e.str());
      if (messageType == cmake::FATAL_ERROR) {
        return false;
      }
    }
    gg->CreateGenerationObjects();
    gg->GenerateImportFile(fname_abs);
  }

  std::string listFile = cmSystemTools::CollapseFullPath(
    fname, this->Makefile->GetCurrentSourceDirectory());
  if (optional && !cmSystemTools::FileExists(listFile.c_str())) {
    if (!resultVarName.empty()) {
      this->Makefile->AddDefinition(resultVarName, "NOTFOUND");
    }
    return true;
  }

  bool readit =
    this->Makefile->ReadDependentFile(listFile.c_str(), noPolicyScope);

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

  if (!optional && !readit && !cmSystemTools::GetFatalErrorOccured()) {
    std::string m = "could not find load file:\n"
                    "  ";
    m += fname;
    this->SetError(m);
    return false;
  }
  return true;
}
