package dagro

type edgeNameState struct {
	name    string
	present bool
}

func runAcyclic( *Graph) {
	var  []Edge
	if stringValue(asAttrs(.Graph()), "acyclicer") == "greedy" {
		 = greedyFAS(, func( Edge) float64 { return num(asAttrs(.Edge()), "weight") })
	} else {
		 = dfsFAS()
	}
	for ,  := range  {
		 := asAttrs(.Edge())
		.RemoveEdge()
		["forwardName"] = edgeNameState{name: .Name, present: .HasName}
		["reversed"] = true
		.SetEdge(.W, .V, , nextReversedEdgeName(, .W, .V))
	}
}

func nextReversedEdgeName( *Graph, ,  string) string {
	for {
		 := .uniqueID("rev")
		if !.HasEdge(, , ) {
			return 
		}
	}
}

func dfsFAS( *Graph) []Edge {
	var  []Edge
	,  := map[string]bool{}, map[string]bool{}
	var  func(string)
	 = func( string) {
		if [] {
			return
		}
		[], [] = true, true
		for ,  := range .OutEdges() {
			if [.W] {
				 = append(, )
			} else {
				(.W)
			}
		}
		delete(, )
	}
	// Modern Dagre starts DFS from sources before visiting any remaining
	// components. This makes cycle breaking deterministic when a source feeds
	// into a strongly connected component whose nodes were inserted earlier.
	for ,  := range .Sources() {
		()
	}
	for ,  := range .Nodes() {
		()
	}
	return 
}

func undoAcyclic( *Graph) {
	for ,  := range .Edges() {
		 := asAttrs(.Edge())
		if !boolValue(, "reversed") {
			continue
		}
		.RemoveEdge()
		,  := ["forwardName"].(edgeNameState)
		delete(, "reversed")
		delete(, "forwardName")
		if .present {
			.SetEdge(.W, .V, , .name)
		} else {
			.SetEdge(.W, .V, )
		}
	}
}