// Copyright (c) 2025 Kiel University and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0.
//
// SPDX-License-Identifier: EPL-2.0

package p1cycles

import (
	
	

	basegraph 
	
)

// DFSNodeOrderCycleBreaker ports ELK 0.12.0's depth-first cycle breaker that
// visits outgoing targets in node model order (or enforced group-model order)
// instead of raw edge order.
type DFSNodeOrderCycleBreaker struct{}

func (*DFSNodeOrderCycleBreaker) (
	 *layered.LGraphArena,
	 layered.LGraphID,
) layered.ProcessorConfiguration {
	return layered.GreedyCycleConfiguration()
}

func (*DFSNodeOrderCycleBreaker) (
	 *layered.LGraphArena,
	 layered.LGraphID,
) error {
	 := .Graph()
	 := .LayerlessNodes
	 := make([]bool, len())
	 := make([]bool, len())
	 := make([]layered.LNodeID, 0)
	 := make([]layered.LEdgeID, 0)
	for ,  := range  {
		.Node().ID = 
		if len(.NodeIncomingEdges()) == 0 {
			 = append(, )
		}
	}

	 := basegraph.Get(
		&.Properties, layered.CycleBreakingGroupOrder,
	) == layered.GroupOrderEnforced
	 := basegraph.Get(&.Properties, layered.MaximumModelOrderNodes)

	var  func(layered.LNodeID)
	 = func( layered.LNodeID) {
		 := .Node().ID
		if [] {
			return
		}
		[] = true
		[] = true

		 := make(map[int][]layered.LEdgeID)
		for ,  := range .NodeOutgoingEdges() {
			 := .EdgeTargetNode()
			,  := basegraph.TryGet(
				&.Node().Properties, layered.ModelOrder)
			if ! {
				// Match the Java map-size-derived unique high keys: the first
				// target without model order is visited last.
				 := math.MaxInt - len()
				[] = []layered.LEdgeID{}
				continue
			}
			if  {
				 := basegraph.Get(
					&.Node().Properties, layered.CycleBreakingGroupID)
				 = * + 
			}
			[] = append([], )
		}
		 := make([]int, 0, len())
		for  := range  {
			 = append(, )
		}
		sort.Ints()
		for ,  := range  {
			 := []
			 := [0]
			if .EdgeIsSelfLoop() {
				continue
			}
			 := .EdgeTargetNode()
			if [.Node().ID] {
				 = append(, ...)
			} else {
				()
			}
		}
		[] = false
	}

	for ,  := range  {
		()
	}
	for ,  := range  {
		if ![] {
			()
		}
	}
	for ,  := range  {
		.ReverseEdge(, , true)
		basegraph.Set(&.Graph().Properties, layered.Cyclic, true)
	}
	return nil
}