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

#include <map>
#include <utility>
#include <vector>

#include "cmGeneratorTarget.h"
#include "cmLinkItem.h"
#include "cmMakefile.h"

void cmLinkItemGraphVisitor::VisitItem(cmLinkItem const& item)
{
  if (this->ItemVisited(item)) {
    return;
  }

  this->OnItem(item);

  this->VisitLinks(item, item);
}

void cmLinkItemGraphVisitor::VisitLinks(cmLinkItem const& item,
                                        cmLinkItem const& rootItem)
{
  if (item.Target == nullptr) {
    return;
  }

  for (auto const& config : item.Target->Makefile->GetGeneratorConfigs(
         cmMakefile::IncludeEmptyConfig)) {
    this->VisitLinks(item, rootItem, config);
  }
}

void cmLinkItemGraphVisitor::VisitLinks(cmLinkItem const& item,
                                        cmLinkItem const& rootItem,
                                        std::string const& config)
{
  auto const& target = *item.Target;

  DependencyMap dependencies;
  cmLinkItemGraphVisitor::GetDependencies(target, config, dependencies);

  for (auto const& d : dependencies) {
    auto const& dependency = d.second;
    auto const& dependencyType = dependency.first;
    auto const& dependee = dependency.second;
    this->VisitItem(dependee);

    if (this->LinkVisited(item, dependee)) {
      continue;
    }

    this->OnDirectLink(item, dependee, dependencyType);

    if (rootItem.AsStr() != item.AsStr()) {
      this->OnIndirectLink(rootItem, dependee);
    }

    // Visit all the direct and indirect links.
    this->VisitLinks(dependee, dependee);
    this->VisitLinks(dependee, item);
    this->VisitLinks(dependee, rootItem);
  }
}

bool cmLinkItemGraphVisitor::ItemVisited(cmLinkItem const& item)
{
  auto& collection = this->VisitedItems;

  bool const visited = collection.find(item.AsStr()) != collection.cend();

  if (!visited) {
    collection.insert(item.AsStr());
  }

  return visited;
}

bool cmLinkItemGraphVisitor::LinkVisited(cmLinkItem const& depender,
                                         cmLinkItem const& dependee)
{
  auto const link = std::make_pair<>(depender.AsStr(), dependee.AsStr());

  bool const linkVisited =
    this->VisitedLinks.find(link) != this->VisitedLinks.cend();

  if (!linkVisited) {
    this->VisitedLinks.insert(link);
  }

  return linkVisited;
}

void cmLinkItemGraphVisitor::GetDependencies(cmGeneratorTarget const& target,
                                             std::string const& config,
                                             DependencyMap& dependencies)
{
  auto implementationLibraries = target.GetLinkImplementationLibraries(config);
  if (implementationLibraries != nullptr) {
    for (auto const& lib : implementationLibraries->Libraries) {
      auto const& name = lib.AsStr();
      dependencies[name] = Dependency(DependencyType::LinkPrivate, lib);
    }
  }

  auto interfaceLibraries =
    target.GetLinkInterfaceLibraries(config, &target, true);
  if (interfaceLibraries != nullptr) {
    for (auto const& lib : interfaceLibraries->Libraries) {
      auto const& name = lib.AsStr();
      if (dependencies.find(name) != dependencies.cend()) {
        dependencies[name] = Dependency(DependencyType::LinkPublic, lib);
      } else {
        dependencies[name] = Dependency(DependencyType::LinkInterface, lib);
      }
    }
  }

  std::vector<cmGeneratorTarget*> objectLibraries;
  target.GetObjectLibrariesCMP0026(objectLibraries);
  for (auto const& lib : objectLibraries) {
    auto const& name = lib->GetName();
    if (dependencies.find(name) == dependencies.cend()) {
      auto objectItem = cmLinkItem(lib, false, lib->GetBacktrace());
      dependencies[name] = Dependency(DependencyType::Object, objectItem);
    }
  }

  auto const& utilityItems = target.GetUtilityItems();
  for (auto const& item : utilityItems) {
    auto const& name = item.AsStr();
    if (dependencies.find(name) == dependencies.cend()) {
      dependencies[name] = Dependency(DependencyType::Utility, item);
    }
  }
}
