/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "cmIncludeCommand.h"

// cmIncludeCommand
bool cmIncludeCommand::InitialPass(std::vector<std::string> const& args,
                                   cmExecutionStatus&)
{
  if (args.size() < 1 || 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.c_str();
    }
  }

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

  cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
  if (gg->IsExportedTargetsFile(fname_abs)) {
    const char* modal = 0;
    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.c_str(), 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;
}
