// Copyright 2014 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.devtools.build.lib.graph;

import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.toCollection;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 *  <p> The DFS class encapsulates a depth-first search visitation, including
 *  the order in which nodes are to be visited relative to their successors
 *  (PREORDER/POSTORDER), whether the forward or transposed graph is to be
 *  used, and which nodes have been seen already. </p>
 *
 *  <p> A variety of common uses of DFS are offered through methods of
 *  Digraph; however clients can use this class directly for maximum
 *  flexibility.  See the implementation of
 *  Digraph.getStronglyConnectedComponents() for an example. </p>
 *
 *  <p> Clients should not modify the enclosing Digraph instance of a DFS
 *  while a traversal is in progress. </p>
 */
public class DFS<T> {

  // (Preferred over a boolean to avoid parameter confusion.)
  public enum Order {
    PREORDER,
    POSTORDER
  }

  private final Order order; // = (PREORDER|POSTORDER)

  private final Comparator<Node<T>> edgeOrder;

  private final boolean transpose;

  private final Set<Node<T>> marked = new HashSet<>();

  /**
   *  Constructs a DFS instance for searching over the enclosing Digraph
   *  instance, using the specified visitation parameters.
   *
   *  @param order PREORDER or POSTORDER, determines node visitation order
   *  @param edgeOrder an ordering in which the edges originating from the same
   *      node should be visited (if null, the order is unspecified)
   *  @param transpose iff true, the graph is implicitly transposed during
   *  visitation.
   */
  public DFS(Order order, final Comparator<? super T> edgeOrder, boolean transpose) {
    this.order = order;
    this.transpose = transpose;

    this.edgeOrder = (edgeOrder == null) ? null : comparing(Node::getLabel, edgeOrder::compare);
  }

  public DFS(Order order, boolean transpose) {
    this(order, null, transpose);
  }

  /**
   *  Returns the (immutable) set of nodes visited so far.
   */
  public Set<Node<T>> getMarked() {
    return Collections.unmodifiableSet(marked);
  }

  public void visit(Node<T> node, GraphVisitor<T> visitor) {
    if (!marked.add(node)) {
      return;
    }

    if (order == Order.PREORDER) {
      visitor.visitNode(node);
    }

    Collection<Node<T>> edgeTargets = transpose
        ? node.getPredecessors() : node.getSuccessors();
    if (edgeOrder != null) {
      List<Node<T>> mutableNodeList =
          edgeTargets.stream().sorted(edgeOrder).collect(toCollection(ArrayList::new));
      edgeTargets = mutableNodeList;
    }

    for (Node<T> v: edgeTargets) {
      visit(v, visitor);
    }

    if (order == Order.POSTORDER) {
      visitor.visitNode(node);
    }
  }
}
