/* 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 <map>
#include <utility>

#include <cm/memory>

#include "cmsys/FStream.hxx"

#include "cmExecutionStatus.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmProperty.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetLinkLibraryType.h"
#include "cmake.h"

class cmListFileBacktrace;

static void FinalAction(cmMakefile& makefile, std::string const& filename,
                        bool append)
{
  // Use copy-if-different if not appending.
  std::unique_ptr<cmsys::ofstream> foutPtr;
  if (append) {
    const auto openmodeApp = std::ios::app;
    foutPtr = cm::make_unique<cmsys::ofstream>(filename.c_str(), openmodeApp);
  } else {
    std::unique_ptr<cmGeneratedFileStream> ap(
      new cmGeneratedFileStream(filename, true));
    ap->SetCopyIfDifferent(true);
    foutPtr = std::move(ap);
  }
  std::ostream& fout = *foutPtr;

  if (!fout) {
    cmSystemTools::Error("Error Writing " + filename);
    cmSystemTools::ReportLastSystemError("");
    return;
  }

  // Collect dependency information about all library targets built in
  // the project.
  cmake* cm = makefile.GetCMakeInstance();
  cmGlobalGenerator* global = cm->GetGlobalGenerator();
  const auto& 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 (const auto& local : locals) {
    for (auto const& tgt : local->GetTargets()) {
      // 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 = cmStrCat(target.GetName(), "_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 = cmStrCat(li.first, "_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 (cmProp 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";
}

bool cmExportLibraryDependenciesCommand(std::vector<std::string> const& args,
                                        cmExecutionStatus& status)
{
  if (args.empty()) {
    status.SetError("called with incorrect number of arguments");
    return false;
  }

  std::string const& filename = args[0];
  bool const append = args.size() > 1 && args[1] == "APPEND";
  status.GetMakefile().AddGeneratorAction(
    [filename, append](cmLocalGenerator& lg, const cmListFileBacktrace&) {
      FinalAction(*lg.GetMakefile(), filename, append);
    });

  return true;
}
