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

#include <algorithm>
#include <cassert>
#include <cstddef>
#include <limits>

size_t const cmComputeComponentGraph::INVALID_COMPONENT =
  std::numeric_limits<size_t>::max();

cmComputeComponentGraph::cmComputeComponentGraph(Graph const& input)
  : InputGraph(input)
{
}

cmComputeComponentGraph::~cmComputeComponentGraph() = default;

void cmComputeComponentGraph::Compute()
{
  // Identify components.
  this->Tarjan();

  // Compute the component graph.
  this->ComponentGraph.resize(0);
  this->ComponentGraph.resize(this->Components.size());
  this->TransferEdges();
}

void cmComputeComponentGraph::Tarjan()
{
  size_t n = this->InputGraph.size();
  TarjanEntry entry = { 0, 0 };
  this->TarjanEntries.resize(0);
  this->TarjanEntries.resize(n, entry);
  this->TarjanComponents.resize(0);
  this->TarjanComponents.resize(n, INVALID_COMPONENT);
  this->TarjanWalkId = 0;
  this->TarjanVisited.resize(0);
  this->TarjanVisited.resize(n, 0);
  for (size_t i = 0; i < n; ++i) {
    // Start a new DFS from this node if it has never been visited.
    if (!this->TarjanVisited[i]) {
      assert(this->TarjanStack.empty());
      ++this->TarjanWalkId;
      this->TarjanIndex = 0;
      this->TarjanVisit(i);
    }
  }
}

void cmComputeComponentGraph::TarjanVisit(size_t i)
{
  // We are now visiting this node.
  this->TarjanVisited[i] = this->TarjanWalkId;

  // Initialize the entry.
  this->TarjanEntries[i].Root = i;
  this->TarjanComponents[i] = INVALID_COMPONENT;
  this->TarjanEntries[i].VisitIndex = ++this->TarjanIndex;
  this->TarjanStack.push(i);

  // Follow outgoing edges.
  EdgeList const& nl = this->InputGraph[i];
  for (cmGraphEdge const& ni : nl) {
    size_t j = ni;

    // Ignore edges to nodes that have been reached by a previous DFS
    // walk.  Since we did not reach the current node from that walk
    // it must not belong to the same component and it has already
    // been assigned to a component.
    if (this->TarjanVisited[j] > 0 &&
        this->TarjanVisited[j] < this->TarjanWalkId) {
      continue;
    }

    // Visit the destination if it has not yet been visited.
    if (!this->TarjanVisited[j]) {
      this->TarjanVisit(j);
    }

    // If the destination has not yet been assigned to a component,
    // check if it has a better root for the current object.
    if (this->TarjanComponents[j] == INVALID_COMPONENT) {
      if (this->TarjanEntries[this->TarjanEntries[j].Root].VisitIndex <
          this->TarjanEntries[this->TarjanEntries[i].Root].VisitIndex) {
        this->TarjanEntries[i].Root = this->TarjanEntries[j].Root;
      }
    }
  }

  // Check if we have found a component.
  if (this->TarjanEntries[i].Root == i) {
    // Yes.  Create it.
    size_t c = this->Components.size();
    this->Components.emplace_back();
    NodeList& component = this->Components[c];

    // Populate the component list.
    size_t j;
    do {
      // Get the next member of the component.
      j = this->TarjanStack.top();
      this->TarjanStack.pop();

      // Assign the member to the component.
      this->TarjanComponents[j] = c;
      this->TarjanEntries[j].Root = i;

      // Store the node in its component.
      component.push_back(j);
    } while (j != i);

    // Sort the component members for clarity.
    std::sort(component.begin(), component.end());
  }
}

void cmComputeComponentGraph::TransferEdges()
{
  // Map inter-component edges in the original graph to edges in the
  // component graph.
  size_t n = this->InputGraph.size();
  for (size_t i = 0; i < n; ++i) {
    size_t i_component = this->TarjanComponents[i];
    EdgeList const& nl = this->InputGraph[i];
    for (cmGraphEdge const& ni : nl) {
      size_t j = ni;
      size_t j_component = this->TarjanComponents[j];
      if (i_component != j_component) {
        // We do not attempt to combine duplicate edges, but instead
        // store the inter-component edges with suitable multiplicity.
        this->ComponentGraph[i_component].emplace_back(
          j_component, ni.IsStrong(), ni.IsCross(), ni.GetBacktrace());
      }
    }
  }
}
