// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package utils

import (
	"bytes"
	"fmt"
)

// This file contains an implementation of an algorithm to check the well-foundedness
// of two-sorted directed graphs. See the paper
// "Well-Founded Two-Sorted Directed Graphs" (https://goo.gl/ipxFKu) for background
// and detailed definitions. Here we give only a high-level overview.
//
// A two-sorted graph is a directed graph that contains two sorts of nodes called circle nodes and
// square nodes. A node in a two-sorted graph is *well-founded* iff it satisfies the
// following recursive definition:
// (i) Leaf nodes are well-founded
// (ii) A circle node is well-founded iff all of its children are well-founded
// (iii) A non-leaf square node is well-founded iff at least one of its children is well-founded.
// (See the paper for a more logically correct definition.)
//
// See the comments on the main function |CheckWellFounded| below for a description
// of the algorithm.

///////////////////////////////////////////////////
// Node type
//
// A |Node| is a node in a directed graph. A user of this library is responsible
// for implementing this interface. This library will use the Go equality operator
// to compare instances of |Node| and it is the responsibility of the user
// to ensure that x == y iff x and y represent the same logical node.
///////////////////////////////////////////////////

type Node interface {
	// Returns the list of children of this node.
	OutEdges() []OutEdge

	// Returns whether or not this node is a square node.
	IsSquare() bool

	// SetKnownWellFounded is invoked by the algorithm in order to set the
	// fact that the algorithm has determined that this node is well-founded.
	// An implementation of |Node| should cache this--even between different
	// invocations of the algorithm on different starting nodes--and return
	// |true| from the method |KnownWellFounded| just in case this method has
	// ever been invoked.  In this way any nodes verified to be well-founded during
	// one run of the algorithm do not need to be checked during a later run of the
	// algorithm on a different starting node.
	SetKnownWellFounded()

	// Returns whether or not the function |SetKnownWellFounded| has ever
	// been invoked on this node, during the lifetime of a program using
	// this library.
	KnownWellFounded() bool

	// Returns a human-readable name for this node. Not used by the algorithm
	// but used for generating debugging and error messages.
	Name() string
}

type OutEdge struct {
	// The Label on an edge is opaque data that may be used by the client however it wishes.
	// The algorithm never inspects this data.
	Label interface{}

	// The target node of the out edge.
	Target Node
}

///////////////////////////////////////////////////
// CheckWellFounded function
//
// This is the main public function.
///////////////////////////////////////////////////

// CheckWellFounded checks whether the sub-graph rooted at |root| contains any ill-founded nodes.
// If any ill-founded nodes are detected then a non-nil |CycleDescription| is returned containing
// a cycle of ill-founded nodes. If every node is well-founded then nil is returned.
//
// If the graph contains only circle nodes then well-foundedness is equivalent to
// acyclicality and so the returned cycle is a proof that the nodes contained in it
// are ill-founded. But in general (if the graph contains square nodes) the returned
// |CycleDescription| is only meant to serve as an example of some of the
// ill-foundedness contained in the subgraph. The cycle is guaranteed to contain only
// ill-founded nodes and the cycle may be considered part of a proof that thes nodes
// are in fact ill-founded. But the cycle does not necessarily contain every
// ill-founded node and it does not
// necessarily constitute a complete proof of the ill-foundedness
// because a graph that contains square nodes is allowed to contain some cycles and still be
// well-founded. The intended application of the returned CycleDescription is to be used to
// describe to a user the location of the ill-foundedness in order to allow the user to modify
// the graph in order to make it well-founded.
//
// This function may be invoked multiple times on different starting nodes during the life
// of a program. If the function is invoked once on node |x| and no ill-foundedness is
// found and then the function is invoked later on node |y| and if node |z| is reachable
// from both |x| and |y| then node |z| will be marked |KnownWellFounded| during the
// first run of the function and so the graph below |z| will not have to be inspected
// during the second run of the function.
//
// Our algorithm proceeds in three phases:
// (1) Phase 1 consists of a depth-first traversal of the graph whose purpose is two-fold:
//     (a) To prove directly that as many nodes as possible are well-founded and mark them
//         so by invoking SetKnownWellFounded().
//     (b) To prepare for phase 2 by constructing two sets of nodes called the |foundationSet| and
//         the |pendingSet|
//     See the comments at |checkWellFoundedPhase1| for more details.
//
// In many cases phase 1 will be able to prove that every node is well-founded and so the algorithm
// will terminate without entering phase 2. This is the case for example if the graph has no
// cycles at all.
//
// (2) The purpose of phase 2 is to propogate the |KnownWellFounded| property to the remaining well-founded
//     nodes (the ones that could not be verified as well-founded during phase 1.) Phase 2 proceeds in
//     multiple rounds. During each round the |KnownWellFounded| property is propogated from the
//     |foundationSet| to the |pendingSet|. See the comments at |checkWellFoundedPhase2| for more details.
//
//  If there are no ill-founded nodes then the algorithm terminates after phase 2.
//
// (3) Phase 3 of the algorithm consists of building a |CycleDescription| in the case that there are ill-founded
//     nodes.  See the method |findKnownIllFoundedCycle|.

func CheckWellFounded(root Node) *CycleDescription {
	return checkWellFounded(root, nil)
}

// checkWellFounded is a package-private version of CheckWellFounded intendend to be invoked by tests.
// It offers a second parameter |debugDataRequest|. If this is non-nil then its fields will be filled
// in with debugging data about the output of phase 1.
func checkWellFounded(root Node, debugDataRequest *debugData) *CycleDescription {
	if root == nil {
		return nil
	}
	finder := makeCycleFinder()
	finder.debugDataRequest = debugDataRequest
	holder := finder.holderForNode(root)
	return finder.checkWellFounded(holder)
}

///////////////////////////////////////////////////
/// cycleFinder type
///
/// A cycleFinder is an object that holds state during the execution of the algorithm.
///////////////////////////////////////////////////
type cycleFinder struct {

	// Maps each node seen by the computation to its holder. Note that this assumes
	// that the implementation of Node uses values that are comparable and
	// obey identity semantics.
	nodeToHolder map[Node]*nodeHolder

	foundationSet, pendingSet NodeSet

	visitationIndex int

	debugDataRequest *debugData
}

type debugData struct {
	initialPendingSet    []Node
	initialFoundationSet []Node
}

func makeCycleFinder() cycleFinder {
	finder := cycleFinder{}
	finder.nodeToHolder = make(map[Node]*nodeHolder)
	finder.foundationSet = MakeNodeSet()
	finder.pendingSet = MakeNodeSet()
	return finder
}

// checkWellFounded contains the top-level implementation of the algorithm.
func (finder *cycleFinder) checkWellFounded(nodeHolder *nodeHolder) *CycleDescription {
	if nodeHolder.node.KnownWellFounded() {
		// This node is already known to be well-founded because of an earlier
		// execution of the algorithm.
		return nil
	}

	// Perform phase 1.
	finder.checkWellFoundedPhase1(nodeHolder)

	// In tests we pass back some debugging information here.
	if finder.debugDataRequest != nil {
		finder.debugDataRequest.initialPendingSet = finder.pendingSet.ToNodeSlice()
		finder.debugDataRequest.initialFoundationSet = finder.foundationSet.ToNodeSlice()
	}

	// All nodes have been verified as well-founded.
	if finder.pendingSet.Empty() {
		return nil
	}

	// Perform phase 2.
	finder.checkWellFoundedPhase2()

	// All nodes have been verified as well-founded.
	if finder.pendingSet.Empty() {
		return nil
	}

	// If we are here then there is at least one ill-founded node.

	// In order to build a canonical cycle description, find the illfounded
	// node with the least visitation order.
	var minVisitationOrder int
	var minIllfoundedNode Node = nil
	for n, _ := range finder.pendingSet.elements {
		if minIllfoundedNode == nil || n.visitationOrder < minVisitationOrder {
			minVisitationOrder = n.visitationOrder
			minIllfoundedNode = n.node
		}
	}

	// Starting from the ill-founded node with the least visitation order,
	// build a canonical cycle.
	freshCycleFinder := makeCycleFinder()
	holder := freshCycleFinder.holderForNode(minIllfoundedNode)
	return freshCycleFinder.findKnownIllFoundedCycle(holder, nil)
}

// checkWellFoundedPhase1 is a recursive helper function that does a depth-first traversal
// of the graph rooted at |nodeHolder|. The goal of phase 1 is to mark as many
// of the nodes as possible as |KnownWellFounded| and to set up the |pendingSet|,
// the |foundationSet|, and the |parentsToBeNotified| sets so that the remaining
// well-founded nodes will be marked as |KnownWellFounded| in phase 2.
//
// In more detail the following steps are performed for each node x:
// (a1) If it can be verified during the traversal that x is well-founded then
// x will be marked as |KnownWellFounded|. This occurs if x is a leaf, or x
// is a circle and each child node of x is known well-founded before being
// visited as a child of x, or x is a square and at-least one child node of x
// is known well-founded before being visited as a child of x.
// (a2) Otherwise if it cannot be determined during traveral that x is well-founded then
//   (i) x is added to the |pendingSet|.
//   (ii) x is added to the |parentsToBeNotified| set of all of its children.
// (b) In step (a1) if at the time x is found to be well-founded x already has
// some parent node x' in its |parentsToBeNotified| set (meaning that step a2 occurred
// earlier for x' and so x' is in the |pendingSet|) then x is added to the |foundationSet|.
// In phase 2, the fact that x is in the foundation set and x' is in the pending set will be
// used to propogate known-wellfoundedness to x'.
func (finder *cycleFinder) checkWellFoundedPhase1(nodeHolder *nodeHolder) {
	if nodeHolder.node.KnownWellFounded() {
		// This node is known to be well-founded before being visited.
		// This occurs when the node was marked |KnownWellFounded| during a
		// previous run of the algorithm. It follows that all nodes reachable
		// from this node have also been so marked. We therefore don't need
		// to traverse the part of the graph below this node during this run
		// of the algorithm and so we treat this node as a leaf node.
		nodeHolder.state = vsVisitEnded
		return
	}

	// Mark the visit as started.
	nodeHolder.state = vsVisitStarted

	// Next we examine each of the children and recurse into the unvisited ones.
	sawUnverifiedChild := false
	for _, edge := range nodeHolder.node.OutEdges() {
		childHolder := finder.holderForNode(edge.Target)
		if childHolder.state == vsUnvisited {
			// Recursively visit this child.
			finder.checkWellFoundedPhase1(childHolder)
		}

		// After having visited a child we use the results to update the status of this node.
		// We could express the logic here more concisely, but  the logic is easier
		// to understand if we treat circles and squares seperately,
		if nodeHolder.node.IsSquare() {
			if nodeHolder.node.KnownWellFounded() {
				// This square node has already been marked |KnownWellFounded| becuase
				// of an earlier iteration through this loop. There is nothing else to do.
				continue
			}
			if childHolder.node.KnownWellFounded() {
				// We mark a square node as |KnownWellFounded| as soon as we can so
				// that if any of its descendants are also parents, the well-foundedness
				// has a chance to propogate to the descendant in a recursive call.
				nodeHolder.node.SetKnownWellFounded()
			} else {
				// This square node is not yet known to be well-founded and the child node
				// is not yet known to be well-founded. Set up a back link from the child.
				childHolder.parentsToBeNotified.Add(nodeHolder)
				sawUnverifiedChild = true
			}
			continue // Done handling the square case.
		}

		// Else the node is a circle. If the child is not yet known to be well-founded
		// set up a back link from the child to this node.
		if !childHolder.node.KnownWellFounded() {
			childHolder.parentsToBeNotified.Add(nodeHolder)
			sawUnverifiedChild = true
		}
	}

	// If a circle node has only well-founded children, or a square node has no children at all,
	// then the node is well-founded.
	if !sawUnverifiedChild && !nodeHolder.node.KnownWellFounded() {
		nodeHolder.node.SetKnownWellFounded()
	}

	// Possibly add this node to the |foundationSet| or the |pendingSet|.
	if nodeHolder.node.KnownWellFounded() {
		if !nodeHolder.parentsToBeNotified.Empty() {
			finder.foundationSet.Add(nodeHolder)
		}
	} else {
		finder.pendingSet.Add(nodeHolder)
	}

	// Mark the visit as ended.
	nodeHolder.state = vsVisitEnded
	return
}

// checkWellFoundedPhase2 performs phase 2 of the algorithm. The goal is to
// propogate known well-foundedness along the back-links that were established
// during phase 1. We have two sets of nodes: the |foundationSet| and the
// |pendingSet|. The |pendingSet| consists of all nodes that are not currently
// known to be well-founded. If the |pendingSet| is not empty when this method
// returns, then the nodes in the |pendingSet| are ill-founded. The |foundationSet|
// consists of the current frontier of the propogation. That is, the |foundationSet|
// consists of the nodes discovered to be well-founded in recent iterations and not yet
// used to propogate well-foundedness. (The |foundationSet| starts with the nodes discovered
// to be well-founded during phase 1, pruned to nodes that have parents that
// are in the |pendingSet|.) We iteratively remove a node n from the foundation set and
// for each of its parents p for which p is in the pending set and for which we can now verify
// well-foundedness, we remove p from the pending set and add it to the foundation set.
func (finder *cycleFinder) checkWellFoundedPhase2() {
	for n := finder.foundationSet.removeRandomElement(); n != nil; n = finder.foundationSet.removeRandomElement() {
		for p, _ := range n.parentsToBeNotified.elements {
			if finder.pendingSet.Contains(p) {
				knownWellFounded := true
				if !p.node.IsSquare() {
					for _, edge := range p.node.OutEdges() {
						child := edge.Target
						if child != p.node && !child.KnownWellFounded() {
							knownWellFounded = false
							break
						}
					}
				}
				if knownWellFounded {
					p.node.SetKnownWellFounded()
					finder.foundationSet.Add(p)
					finder.pendingSet.Remove(p)
				}
			}
		}
	}
}

// A pathElement is a node and one of its out-edges.
type pathElement struct {
	node Node
	edge OutEdge
}

type nodePath []pathElement

// findKnownIllFoundedCycle finds and returns a |CycleDescription| starting from a node that is known
// to be ill-founded. This proceeds by following edges from an ill-founded node to
// an ill-founded child node until a cycle is formed. We return a *canonical* cycle,
// meaning we start from the node with the least possible visit index and follow edges to
// the child node with the least possible visit index. This is done in order to make testing of the algorithm easier.
// We are not concerned with optimizing the performance of phase 3 because in the intended application
// phase 3 can occur at most once in the lifetime of a program: Once an ill-founded node is detected the
// program exits with a cycle description allowing the user to fix the ill-foundedness.
//
// This method is recursive. To initiate the recursion |nodeHolder| should be set to the starting node and
// |path| should be nil. In subsequent recursive calls |nodeHolder| is the current node of the walk and
// |path| is the path from the starting node to the current node.
func (finder *cycleFinder) findKnownIllFoundedCycle(nodeHolder *nodeHolder, path nodePath) *CycleDescription {
	// If this is the start of the recursion initialize the path.
	if path == nil {
		path = make(nodePath, 0)
	}

	// Mark the current node as started
	nodeHolder.state = vsVisitStarted
	for _, edge := range nodeHolder.node.OutEdges() {
		childHolder := finder.holderForNode(edge.Target)
		if childHolder.state == vsVisitStarted {
			// If the child has been started but not finished then we have found a cycle
			// from the child to the current node back to the child.
			path = append(path, pathElement{nodeHolder.node, edge})
			return newCycleDescription(path, childHolder.node, nodeHolder.node)
		} else if !childHolder.node.KnownWellFounded() {
			path = append(path, pathElement{nodeHolder.node, edge})
			return finder.findKnownIllFoundedCycle(childHolder, path)
		}
	}
	panic("Program logic error: Could not find a known ill-founded cycle.")
}

// Returns the nodeHolder for the given node.
func (finder *cycleFinder) holderForNode(node Node) *nodeHolder {
	if holder, found := finder.nodeToHolder[node]; found {
		return holder
	}

	// This is the first time we have seen this node. Assign it a new
	// visitor order.
	holder := newNodeHolder(node, finder.visitationIndex)
	finder.visitationIndex++
	finder.nodeToHolder[node] = holder
	return holder
}

////////////////////////////////////////////////////
// nodeHolder type
////////////////////////////////////////////////////

type visitationState int

const (
	vsUnvisited visitationState = iota
	vsVisitStarted
	vsVisitEnded
)

// A nodeHolder is an internal data structure used by the algorithm.
// It holds one node plus data about that node used by the algorithm.
type nodeHolder struct {
	// The node
	node Node

	parentsToBeNotified NodeSet

	visitationOrder int

	state visitationState
}

func newNodeHolder(node Node, visitationOrder int) *nodeHolder {
	nodeHolder := new(nodeHolder)
	nodeHolder.node = node
	nodeHolder.parentsToBeNotified = MakeNodeSet()
	nodeHolder.state = vsUnvisited
	nodeHolder.visitationOrder = visitationOrder
	return nodeHolder
}

///////////////////////////////////////////////////
/// NodeSet type
///////////////////////////////////////////////////

// A NodeSet is a set of nodeHolders.
type NodeSet struct {
	elements map[*nodeHolder]bool
}

// MakeNodeSet makes a new empty NodeSet.
func MakeNodeSet() NodeSet {
	nodeSet := NodeSet{}
	nodeSet.elements = make(map[*nodeHolder]bool)
	return nodeSet
}

// Add adds a Node to a NodeSet.
func (set *NodeSet) Add(node *nodeHolder) {
	set.elements[node] = true
}

// AddAll adds all the nodes from |otherSet| to |set|.
func (set *NodeSet) AddAll(otherSet NodeSet) {
	for e, _ := range otherSet.elements {
		set.elements[e] = true
	}
}

// Contains returns whether or not |node| is an element of |set|.
func (set *NodeSet) Contains(node *nodeHolder) bool {
	_, ok := set.elements[node]
	return ok
}

func (set *NodeSet) Remove(node *nodeHolder) {
	delete(set.elements, node)
}

func (set *NodeSet) Empty() bool {
	return len(set.elements) == 0
}

// doUntilEmpty repeatedly iterates through the elements of |set| removing
// them and invoking |f|. More precisely, for each element x of |set|,
// x is removed from |set| and then f(x) is invoked.
//
// The function |f| is allowed to mutate |set|. If |f| adds new elements to
// |set| those will also eventually be removed and operated on. Whether or
// not this process converges to an empty set depends entirely on the behavior
// of |f| and it is the caller's responsibility to ensure that it does.
func (set *NodeSet) doUntilEmpty(f func(node *nodeHolder)) {
	for !set.Empty() {
		for n, _ := range set.elements {
			set.Remove(n)
			f(n)
		}
	}
}

// removeRandomElement removes and returns an arbitrary element of |set|
// or nil of |set| is empty.
func (set *NodeSet) removeRandomElement() *nodeHolder {
	for n, _ := range set.elements {
		delete(set.elements, n)
		return n
	}
	return nil
}

func (set *NodeSet) ToNodeSlice() []Node {
	slice := make([]Node, 0, len(set.elements))
	for n, _ := range set.elements {
		slice = append(slice, n.node)
	}
	return slice
}

func (set *NodeSet) Size() int {
	return len(set.elements)
}

// compareNodeSets is a package-private method used in our tests. It returns
// a non-nil error in case expected is not equal to actual.
func compareNodeSets(expected, actual *NodeSet) error {
	for n, _ := range expected.elements {
		if !actual.Contains(n) {
			return fmt.Errorf("%s is in expected but not actual", n.node.Name())
		}
	}
	for n, _ := range actual.elements {
		if !expected.Contains(n) {
			return fmt.Errorf("%s is in actual but not expected", n.node.Name())
		}
	}
	return nil
}

// String returns a human readable string representation of |set|.
func (set *NodeSet) String() string {
	var buffer bytes.Buffer
	fmt.Fprintf(&buffer, "{")
	first := true
	for e, _ := range set.elements {
		if !first {
			fmt.Fprintf(&buffer, ", ")
		}
		fmt.Fprintf(&buffer, "%s", e.node.Name())
		first = false
	}
	fmt.Fprintln(&buffer, "}")
	return buffer.String()
}

///////////////////////////////////////////////////
// CycleDescription type
//
// A |CycleDescription| describes a cycle in a directed graph.
///////////////////////////////////////////////////

type CycleDescription struct {
	First, Last Node
	Path        []OutEdge
}

func (c *CycleDescription) String() string {
	var buffer bytes.Buffer
	fmt.Fprintf(&buffer, "first:%s", c.First.Name())
	fmt.Fprintf(&buffer, ", last:%s", c.Last.Name())
	fmt.Fprintf(&buffer, ", path:{")
	fmt.Fprintf(&buffer, "%s", c.First.Name())
	for _, edge := range c.Path {
		if edge.Target != c.First {
			fmt.Fprintf(&buffer, ", ")
			fmt.Fprintf(&buffer, "%s", edge.Target.Name())
		}
	}
	fmt.Fprintln(&buffer, "}")
	return buffer.String()
}

// newCycleDescription builds a CycleDescription based on the given data.
// |path| should be a nodePath that ends with a cycle. That is it should look like
//  {x1, ->x2}, {x2, ->x3}, {x3, ->x4}, {x4, ->x5}, {x5, ->x2}
//
// |cycleStart| should be the first node of |path| included in the cycle. In
// the above example it would be x2.
//
// |end| should be the last node of the path. In the above example it would be x5.
//
// The return value using our example would be:
// {First: x2, Last: x5, Path:[{x2, x2->x3}, {x3, x3->x4}, {x4, x4->x5}, {x5, x5->x2}]}
func newCycleDescription(path nodePath, cycleStart, end Node) *CycleDescription {
	lastNode := path[len(path)-1].node
	if lastNode != end {
		panic(fmt.Sprintf("%s != %s", lastNode.Name(), end.Name()))
	}
	lastTarget := path[len(path)-1].edge.Target
	if lastTarget != cycleStart {
		panic(fmt.Sprintf("(%T)%s != (%T)%s", lastTarget, lastTarget.Name(), cycleStart, cycleStart.Name()))
	}
	description := CycleDescription{}
	description.First = cycleStart
	description.Last = end
	description.Path = make([]OutEdge, 0, len(path))
	for _, element := range path {
		if len(description.Path) > 0 || element.node == cycleStart {
			description.Path = append(description.Path, element.edge)
		}
	}
	if description.Path[len(description.Path)-1].Target != cycleStart {
		panic(fmt.Sprintf("%s != %s", description.Path[len(description.Path)-1].Target.Name(), cycleStart.Name()))
	}
	return &description
}
