/* 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 "cmsys/FStream.hxx"
#include <map>
#include <memory> // IWYU pragma: keep
#include <utility>

#include "cmAlgorithms.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmStateTypes.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetLinkLibraryType.h"
#include "cmake.h"

class cmExecutionStatus;

bool cmExportLibraryDependenciesCommand::InitialPass(
  std::vector<std::string> const& args, cmExecutionStatus&)
{
  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.
  std::unique_ptr<cmsys::ofstream> foutPtr;
  if (this->Append) {
    foutPtr =
      cm::make_unique<cmsys::ofstream>(this->Filename.c_str(), std::ios::app);
  } else {
    std::unique_ptr<cmGeneratedFileStream> ap(
      new cmGeneratedFileStream(this->Filename, true));
    ap->SetCopyIfDifferent(true);
    foutPtr = std::move(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 (cmMakefile* local : locals) {
    const cmTargets& tgts = local->GetTargets();
    for (auto const& tgt : tgts) {
      // Get the current target.
      cmTarget const& target = tgt.second;

      // Skip non-library targets.
      if (target.GetType() < cmStateEnums::STATIC_LIBRARY ||
          target.GetType() > cmStateEnums::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::LibraryID const& li : libs) {
        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 (auto const& i : libDepsNew) {
    if (!i.second.empty()) {
      fout << "  set(\"" << i.first << "\" \"" << i.second << "\")\n";
    }
  }
  fout << "else()\n";
  fout << "  # Information for CMake 2.4 and lower.\n";
  for (auto const& i : libDepsOld) {
    if (!i.second.empty()) {
      fout << "  set(\"" << i.first << "\" \"" << i.second << "\")\n";
    }
  }
  for (auto const& i : libTypes) {
    if (i.second != "general") {
      fout << "  set(\"" << i.first << "\" \"" << i.second << "\")\n";
    }
  }
  fout << "endif()\n";
}
