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

#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmVersion.h"
#include "cmake.h"

#include <cm_auto_ptr.hxx>

bool cmExportLibraryDependenciesCommand::InitialPass(
  std::vector<std::string> const& args, cmExecutionStatus&)
{
  if (this->Disallowed(
        cmPolicies::CMP0033,
        "The export_library_dependencies command should not be called; "
        "see CMP0033.")) {
    return true;
  }
  if (args.empty()) {
    this->SetError("called with incorrect number of arguments");
    return false;
  }

  // store the arguments for the final pass
  this->Filename = args[0];
  this->Append = false;
  if (args.size() > 1) {
    if (args[1] == "APPEND") {
      this->Append = true;
    }
  }
  return true;
}

void cmExportLibraryDependenciesCommand::FinalPass()
{
  // export_library_dependencies() shouldn't modify anything
  // ensure this by calling a const method
  this->ConstFinalPass();
}

void cmExportLibraryDependenciesCommand::ConstFinalPass() const
{
  // Use copy-if-different if not appending.
  CM_AUTO_PTR<cmsys::ofstream> foutPtr;
  if (this->Append) {
    CM_AUTO_PTR<cmsys::ofstream> ap(
      new cmsys::ofstream(this->Filename.c_str(), std::ios::app));
    foutPtr = ap;
  } else {
    CM_AUTO_PTR<cmGeneratedFileStream> ap(
      new cmGeneratedFileStream(this->Filename.c_str(), true));
    ap->SetCopyIfDifferent(true);
    foutPtr = ap;
  }
  std::ostream& fout = *foutPtr;

  if (!fout) {
    cmSystemTools::Error("Error Writing ", this->Filename.c_str());
    cmSystemTools::ReportLastSystemError("");
    return;
  }

  // Collect dependency information about all library targets built in
  // the project.
  cmake* cm = this->Makefile->GetCMakeInstance();
  cmGlobalGenerator* global = cm->GetGlobalGenerator();
  const std::vector<cmMakefile*>& locals = global->GetMakefiles();
  std::map<std::string, std::string> libDepsOld;
  std::map<std::string, std::string> libDepsNew;
  std::map<std::string, std::string> libTypes;
  for (std::vector<cmMakefile*>::const_iterator i = locals.begin();
       i != locals.end(); ++i) {
    const cmTargets& tgts = (*i)->GetTargets();
    for (cmTargets::const_iterator l = tgts.begin(); l != tgts.end(); ++l) {
      // Get the current target.
      cmTarget const& target = l->second;

      // Skip non-library targets.
      if (target.GetType() < cmState::STATIC_LIBRARY ||
          target.GetType() > cmState::MODULE_LIBRARY) {
        continue;
      }

      // Construct the dependency variable name.
      std::string targetEntry = target.GetName();
      targetEntry += "_LIB_DEPENDS";

      // Construct the dependency variable value with the direct link
      // dependencies.
      std::string valueOld;
      std::string valueNew;
      cmTarget::LinkLibraryVectorType const& libs =
        target.GetOriginalLinkLibraries();
      for (cmTarget::LinkLibraryVectorType::const_iterator li = libs.begin();
           li != libs.end(); ++li) {
        std::string ltVar = li->first;
        ltVar += "_LINK_TYPE";
        std::string ltValue;
        switch (li->second) {
          case GENERAL_LibraryType:
            valueNew += "general;";
            ltValue = "general";
            break;
          case DEBUG_LibraryType:
            valueNew += "debug;";
            ltValue = "debug";
            break;
          case OPTIMIZED_LibraryType:
            valueNew += "optimized;";
            ltValue = "optimized";
            break;
        }
        std::string lib = li->first;
        if (cmTarget* libtgt = global->FindTarget(lib)) {
          // Handle simple output name changes.  This command is
          // deprecated so we do not support full target name
          // translation (which requires per-configuration info).
          if (const char* outname = libtgt->GetProperty("OUTPUT_NAME")) {
            lib = outname;
          }
        }
        valueOld += lib;
        valueOld += ";";
        valueNew += lib;
        valueNew += ";";

        std::string& ltEntry = libTypes[ltVar];
        if (ltEntry.empty()) {
          ltEntry = ltValue;
        } else if (ltEntry != ltValue) {
          ltEntry = "general";
        }
      }
      libDepsNew[targetEntry] = valueNew;
      libDepsOld[targetEntry] = valueOld;
    }
  }

  // Generate dependency information for both old and new style CMake
  // versions.
  const char* vertest =
    "\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" GREATER 2.4";
  fout << "# Generated by CMake\n\n";
  fout << "if(" << vertest << ")\n";
  fout << "  # Information for CMake 2.6 and above.\n";
  for (std::map<std::string, std::string>::const_iterator i =
         libDepsNew.begin();
       i != libDepsNew.end(); ++i) {
    if (!i->second.empty()) {
      fout << "  set(\"" << i->first << "\" \"" << i->second << "\")\n";
    }
  }
  fout << "else()\n";
  fout << "  # Information for CMake 2.4 and lower.\n";
  for (std::map<std::string, std::string>::const_iterator i =
         libDepsOld.begin();
       i != libDepsOld.end(); ++i) {
    if (!i->second.empty()) {
      fout << "  set(\"" << i->first << "\" \"" << i->second << "\")\n";
    }
  }
  for (std::map<std::string, std::string>::const_iterator i = libTypes.begin();
       i != libTypes.end(); ++i) {
    if (i->second != "general") {
      fout << "  set(\"" << i->first << "\" \"" << i->second << "\")\n";
    }
  }
  fout << "endif()\n";
  return;
}
