// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/// A library to work with graphs. It contains a couple algorithms, including
/// Tarjan's algorithm to compute strongly connected components in a graph and
/// Cooper et al's dominator algorithm.
///
/// Portions of the code in this library was adapted from
/// `package:analyzer/src/generated/collection_utilities.dart`.
// TODO(sigmund): move this into a shared place, like quiver?
library dart2js_info.src.graph;

import 'dart:math' as math;

abstract class Graph<N> {
  Iterable<N> get nodes;
  bool get isEmpty;
  int get nodeCount;
  Iterable<N> targetsOf(N source);
  Iterable<N> sourcesOf(N source);

  /// Run a topological sort of the graph. Since the graph may contain cycles,
  /// this results in a list of strongly connected components rather than a list
  /// of nodes. The nodes in each strongly connected components only have edges
  /// that point to nodes in the same component or earlier components.
  List<List<N>> computeTopologicalSort() {
    _SccFinder<N> finder = _SccFinder<N>(this);
    return finder.computeTopologicalSort();
  }

  /// Whether [source] can transitively reach [target].
  bool containsPath(N source, N target) {
    Set<N> seen = <N>{};
    bool helper(N node) {
      if (identical(node, target)) return true;
      if (!seen.add(node)) return false;
      return targetsOf(node).any(helper);
    }

    return helper(source);
  }

  /// Returns all nodes reachable from [root] in post order.
  Iterable<N> postOrder(N root) sync* {
    var seen = <N>{};
    Iterable<N> helper(N n) sync* {
      if (!seen.add(n)) return;
      for (var x in targetsOf(n)) {
        yield* helper(x);
      }
      yield n;
    }

    yield* helper(root);
  }

  /// Returns an iterable of all nodes reachable from [root] in preorder.
  Iterable<N> preOrder(N root) sync* {
    var seen = <N>{};
    var stack = <N>[root];
    while (stack.isNotEmpty) {
      var next = stack.removeLast();
      if (!seen.contains(next)) {
        seen.add(next);
        yield next;
        stack.addAll(targetsOf(next));
      }
    }
  }

  /// Returns a list of nodes that form a cycle containing the given node. If
  /// the node is not part of a cycle in this graph, then a list containing only
  /// the node itself will be returned.
  List<N> findCycleContaining(N node) {
    assert(node != null);
    _SccFinder<N> finder = _SccFinder<N>(this);
    return finder._componentContaining(node);
  }

  /// Returns a dominator tree starting from root. This is a new graph, with the
  /// same nodes as this graph, but where edges exist between a node and the
  /// nodes it immediately dominates. For example, this graph:
  ///
  ///       root
  ///       /   \
  ///      a     b
  ///      |    / \
  ///      c   d   e
  ///       \ / \ /
  ///        f   g
  ///
  /// Produces this tree:
  ///
  ///       root
  ///       /|  \
  ///      a |   b
  ///      | |  /|\
  ///      c | d | e
  ///        |   |
  ///        f   g
  ///
  /// Internally we compute dominators using (Cooper, Harvey, and Kennedy's
  /// algorithm)[http://www.cs.rice.edu/~keith/EMBED/dom.pdf].
  Graph<N> dominatorTree(N root) {
    var iDom = (_DominatorFinder(this)..run(root)).immediateDominators;
    var graph = EdgeListGraph<N>();
    for (N node in iDom.keys) {
      if (node != root) graph.addEdge(iDom[node], node);
    }
    return graph;
  }
}

class EdgeListGraph<N> extends Graph<N> {
  /// Edges in the graph.
  final Map<N, Set<N>> _edges = <N, Set<N>>{};

  /// The reverse of _edges.
  final Map<N, Set<N>> _revEdges = <N, Set<N>>{};

  @override
  Iterable<N> get nodes => _edges.keys;
  @override
  bool get isEmpty => _edges.isEmpty;
  @override
  int get nodeCount => _edges.length;

  final _empty = <N>{};

  @override
  Iterable<N> targetsOf(N source) => _edges[source] ?? _empty;
  @override
  Iterable<N> sourcesOf(N source) => _revEdges[source] ?? _empty;

  void addEdge(N source, N target) {
    assert(source != null);
    assert(target != null);
    addNode(source);
    addNode(target);
    _edges[source].add(target);
    _revEdges[target].add(source);
  }

  void addNode(N node) {
    assert(node != null);
    _edges.putIfAbsent(node, () => <N>{});
    _revEdges.putIfAbsent(node, () => <N>{});
  }

  /// Remove the edge from the given [source] node to the given [target] node.
  /// If there was no such edge then the graph will be unmodified: the number of
  /// edges will be the same and the set of nodes will be the same (neither node
  /// will either be added or removed).
  void removeEdge(N source, N target) {
    _edges[source]?.remove(target);
  }

  /// Remove the given node from this graph. As a consequence, any edges for
  /// which that node was either a head or a tail will also be removed.
  void removeNode(N node) {
    _edges.remove(node);
    var sources = _revEdges[node];
    if (sources == null) return;
    for (var source in sources) {
      _edges[source].remove(node);
    }
  }

  /// Remove all of the given nodes from this graph. As a consequence, any edges
  /// for which those nodes were either a head or a tail will also be removed.
  void removeAllNodes(List<N> nodes) => nodes.forEach(removeNode);
}

/// Used by the [SccFinder] to maintain information about the nodes that have
/// been examined. There is an instance of this class per node in the graph.
class _NodeInfo<N> {
  /// Depth of the node corresponding to this info.
  int index = 0;

  /// Depth of the first node in a cycle.
  int lowlink = 0;

  /// Whether the corresponding node is on the stack. Used to remove the need
  /// for searching a collection for the node each time the question needs to be
  /// asked.
  bool onStack = false;

  /// Component that contains the corresponding node.
  List<N> component;

  _NodeInfo(int depth)
      : index = depth,
        lowlink = depth,
        onStack = false;
}

/// Implements Tarjan's Algorithm for finding the strongly connected components
/// in a graph.
class _SccFinder<N> {
  /// The graph to process.
  final Graph<N> _graph;

  /// The index used to uniquely identify the depth of nodes.
  int _index = 0;

  /// Nodes that are being visited in order to identify components.
  final List<N> _stack = <N>[];

  /// Information associated with each node.
  final Map<N, _NodeInfo<N>> _info = <N, _NodeInfo<N>>{};

  /// All strongly connected components found, in topological sort order (each
  /// node in a strongly connected component only has edges that point to nodes
  /// in the same component or earlier components).
  final List<List<N>> _allComponents = <List<N>>[];

  _SccFinder(this._graph);

  /// Return a list containing the nodes that are part of the strongly connected
  /// component that contains the given node.
  List<N> _componentContaining(N node) => _strongConnect(node).component;

  /// Run Tarjan's algorithm and return the resulting list of strongly connected
  /// components. The list is in topological sort order (each node in a strongly
  /// connected component only has edges that point to nodes in the same
  /// component or earlier components).
  List<List<N>> computeTopologicalSort() {
    for (N node in _graph.nodes) {
      var nodeInfo = _info[node];
      if (nodeInfo == null) _strongConnect(node);
    }
    return _allComponents;
  }

  /// Remove and return the top-most element from the stack.
  N _pop() {
    N node = _stack.removeAt(_stack.length - 1);
    _info[node].onStack = false;
    return node;
  }

  /// Add the given node to the stack.
  void _push(N node) {
    _info[node].onStack = true;
    _stack.add(node);
  }

  /// Compute the strongly connected component that contains the given node as
  /// well as any components containing nodes that are reachable from the given
  /// component.
  _NodeInfo<N> _strongConnect(N v) {
    // Set the depth index for v to the smallest unused index
    var vInfo = _NodeInfo<N>(_index++);
    _info[v] = vInfo;
    _push(v);

    for (N w in _graph.targetsOf(v)) {
      var wInfo = _info[w];
      if (wInfo == null) {
        // Successor w has not yet been visited; recurse on it
        wInfo = _strongConnect(w);
        vInfo.lowlink = math.min(vInfo.lowlink, wInfo.lowlink);
      } else if (wInfo.onStack) {
        // Successor w is in stack S and hence in the current SCC
        vInfo.lowlink = math.min(vInfo.lowlink, wInfo.index);
      }
    }

    // If v is a root node, pop the stack and generate an SCC
    if (vInfo.lowlink == vInfo.index) {
      var component = <N>[];
      N w;
      do {
        w = _pop();
        component.add(w);
        _info[w].component = component;
      } while (!identical(w, v));
      _allComponents.add(component);
    }
    return vInfo;
  }
}

/// Computes dominators using (Cooper, Harvey, and Kennedy's
/// algorithm)[http://www.cs.rice.edu/~keith/EMBED/dom.pdf].
class _DominatorFinder<N> {
  final Graph<N> _graph;
  Map<N, N> immediateDominators = {};
  Map<N, int> postOrderId = {};
  _DominatorFinder(this._graph);

  run(N root) {
    immediateDominators[root] = root;
    bool changed = true;
    int i = 0;
    var nodesInPostOrder = _graph.postOrder(root).toList();
    for (var n in nodesInPostOrder) {
      postOrderId[n] = i++;
    }
    var nodesInReversedPostOrder = nodesInPostOrder.reversed;
    while (changed) {
      changed = false;
      for (var n in nodesInReversedPostOrder) {
        if (n == root) continue;
        bool first = true;
        N idom;
        for (var p in _graph.sourcesOf(n)) {
          if (immediateDominators[p] != null) {
            if (first) {
              idom = p;
              first = false;
            } else {
              idom = _intersect(p, idom);
            }
          }
        }
        if (immediateDominators[n] != idom) {
          immediateDominators[n] = idom;
          changed = true;
        }
      }
    }
  }

  N _intersect(N b1, N b2) {
    var finger1 = b1;
    var finger2 = b2;
    while (finger1 != finger2) {
      while (postOrderId[finger1] < postOrderId[finger2]) {
        finger1 = immediateDominators[finger1];
      }
      while (postOrderId[finger2] < postOrderId[finger1]) {
        finger2 = immediateDominators[finger2];
      }
    }
    return finger1;
  }
}
