package layoutgraph

import (
	
	

	
	
)

type pointerSnapshot[ any] struct {
	pointer *
	value   
}

// exactSliceSnapshot retains both the original slice header and every element
// in its backing array. Restoring through the original header preserves
// pointer, length, capacity, and aliases even when a mutation appended into
// spare capacity before rollback.
type exactSliceSnapshot[ ~[],  any] struct {
	original 
	backing  []
}

func captureExactSlice[ ~[],  any]( ) exactSliceSnapshot[, ] {
	if  == nil {
		return exactSliceSnapshot[, ]{}
	}
	 := [:cap()]
	 := make([], len())
	copy(, )
	return exactSliceSnapshot[, ]{original: , backing: }
}

func ( exactSliceSnapshot[, ]) ()  {
	if .original == nil {
		return nil
	}
	copy(.original[:cap(.original)], .backing)
	return .original
}

type exactSliceMapSnapshot[ comparable,  ~[],  any] struct {
	original map[]
	values   map[]exactSliceSnapshot[, ]
}

func captureExactSliceMap[ comparable,  ~[],  any]( map[]) exactSliceMapSnapshot[, , ] {
	 := exactSliceMapSnapshot[, , ]{original: }
	if  == nil {
		return 
	}
	.values = make(map[]exactSliceSnapshot[, ], len())
	for ,  := range  {
		.values[] = captureExactSlice()
	}
	return 
}

func ( exactSliceMapSnapshot[, , ]) () map[] {
	if .original == nil {
		return nil
	}
	clear(.original)
	for ,  := range .values {
		.original[] = .restore()
	}
	return .original
}

func snapshotPointer[ any]( *) pointerSnapshot[] {
	if  == nil {
		return pointerSnapshot[]{}
	}
	return pointerSnapshot[]{pointer: , value: *}
}

func ( pointerSnapshot[]) () * {
	if .pointer == nil {
		return nil
	}
	*.pointer = .value
	return .pointer
}

type nodeSnapshot struct {
	value Node

	d2ID          pointerSnapshot[string]
	topLeft       pointerSnapshot[geo.Point]
	fontSize      pointerSnapshot[int]
	fixedTopLeft  pointerSnapshot[geo.Point]
	desiredWidth  pointerSnapshot[float64]
	desiredHeight pointerSnapshot[float64]
	label         pointerSnapshot[Label]
	icon          pointerSnapshot[Icon]

	edges                            exactSliceSnapshot[[]*Edge, *Edge]
	nears                            map[*Node]struct{}
	loopOffsets                      map[geo.Orientation]float64
	longDistanceNeighborRequirements map[*Node]LongDistanceNeighborRequirements
}

type edgeSnapshot struct {
	value Edge

	d2ID                 pointerSnapshot[string]
	points               exactSliceSnapshot[[]*geo.Point, *geo.Point]
	pointValues          []pointerSnapshot[geo.Point]
	label                pointerSnapshot[Label]
	sourceArrowheadLabel pointerSnapshot[Label]
	targetArrowheadLabel pointerSnapshot[Label]
	fromTableColumnIndex pointerSnapshot[int]
	toTableColumnIndex   pointerSnapshot[int]
}

type clusterSnapshot struct {
	value          Cluster
	nodes          exactSliceSnapshot[[]*Node, *Node]
	edgeAbductions exactSliceSnapshot[[]*EdgeAbduction, *EdgeAbduction]
}

type sequenceSnapshot struct {
	value          Sequence
	nodes          exactSliceSnapshot[[]*Node, *Node]
	edgeAbductions exactSliceSnapshot[[]*EdgeAbduction, *EdgeAbduction]
}

type treeSnapshot struct {
	value    Tree
	children exactSliceSnapshot[[]*Tree, *Tree]
}

type herdSnapshot struct {
	value              HerdAssignment
	oppositeSidePaired map[*Node]struct{}
	sameSidePaired     map[*Node]struct{}
}

type hierarchySnapshot struct {
	value Hierarchy
	level map[*Node]int
}

type graphSnapshot struct {
	isRootHierarchy bool
	nodes           exactSliceSnapshot[[]*Node, *Node]
	edges           exactSliceSnapshot[[]*Edge, *Edge]
	cellSize        float64

	containers     exactSliceMapSnapshot[*Node, []*Node, *Node]
	clustersRef    map[*Node]*Cluster
	clusters       map[*Node]*Cluster
	trees          exactSliceMapSnapshot[*Node, []*Tree, *Tree]
	nodeToTreeRef  map[*Node]*Tree
	nodeToTree     map[*Node]*Tree
	hubs           exactSliceMapSnapshot[*Node, []*Node, *Node]
	sequencesRef   map[*Node]*Sequence
	sequences      map[*Node]*Sequence
	directionsRef  map[*Node]geo.Orientation
	directions     map[*Node]geo.Orientation
	commonSiblings exactSliceMapSnapshot[*Node, Nodes, *Node]
}

func cloneMapContents[ comparable,  any]( map[]) map[] {
	if len() == 0 {
		return nil
	}
	return maps.Clone()
}

func restoreMap[ comparable,  any](,  map[]) map[] {
	if  == nil {
		return nil
	}
	clear()
	maps.Copy(, )
	return 
}

func captureNode( *Node) nodeSnapshot {
	return nodeSnapshot{
		value:                            *,
		d2ID:                             snapshotPointer(.D2ID),
		topLeft:                          snapshotPointer(.TopLeft),
		fontSize:                         snapshotPointer(.FontSize),
		fixedTopLeft:                     snapshotPointer(.FixedTopLeft),
		desiredWidth:                     snapshotPointer(.DesiredWidth),
		desiredHeight:                    snapshotPointer(.DesiredHeight),
		label:                            snapshotPointer(.Label),
		icon:                             snapshotPointer(.Icon),
		edges:                            captureExactSlice(.Edges),
		nears:                            cloneMapContents(.Nears),
		loopOffsets:                      cloneMapContents(.LoopOffsets),
		longDistanceNeighborRequirements: cloneMapContents(.LongDistanceNeighborRequirements),
	}
}

func ( nodeSnapshot) ( *Node) {
	.d2ID.restore()
	.topLeft.restore()
	.fontSize.restore()
	.fixedTopLeft.restore()
	.desiredWidth.restore()
	.desiredHeight.restore()
	.label.restore()
	.icon.restore()

	* = .value
	.Edges = .edges.restore()
	.Nears = restoreMap(.value.Nears, .nears)
	.LoopOffsets = restoreMap(.value.LoopOffsets, .loopOffsets)
	.LongDistanceNeighborRequirements = restoreMap(.value.LongDistanceNeighborRequirements, .longDistanceNeighborRequirements)
}

func captureEdge( *Edge) edgeSnapshot {
	 := .Points[:cap(.Points)]
	 := make([]pointerSnapshot[geo.Point], len())
	for ,  := range  {
		[] = snapshotPointer()
	}
	return edgeSnapshot{
		value:                *,
		d2ID:                 snapshotPointer(.D2ID),
		points:               captureExactSlice(.Points),
		pointValues:          ,
		label:                snapshotPointer(.Label),
		sourceArrowheadLabel: snapshotPointer(.SourceArrowheadLabel),
		targetArrowheadLabel: snapshotPointer(.TargetArrowheadLabel),
		fromTableColumnIndex: snapshotPointer(.FromTableColumnIndex),
		toTableColumnIndex:   snapshotPointer(.ToTableColumnIndex),
	}
}

func ( edgeSnapshot) ( *Edge) {
	.d2ID.restore()
	.label.restore()
	.sourceArrowheadLabel.restore()
	.targetArrowheadLabel.restore()
	.fromTableColumnIndex.restore()
	.toTableColumnIndex.restore()
	// s.value.Points retains the original slice header. Repair that backing
	// array before reattaching it so rollback preserves aliases to both the
	// route slice and its point objects.
	for ,  := range .pointValues {
		.restore()
	}
	 := .points.restore()

	* = .value
	.Points = 
}

func captureGraph( *Graph) graphSnapshot {
	return graphSnapshot{
		isRootHierarchy: .IsRootHierarchy,
		nodes:           captureExactSlice(.Nodes),
		edges:           captureExactSlice(.Edges),
		cellSize:        .CellSize,
		containers:      captureExactSliceMap(.Containers),
		clustersRef:     .Clusters,
		clusters:        cloneMapContents(.Clusters),
		trees:           captureExactSliceMap(.Trees),
		nodeToTreeRef:   .NodeToTree,
		nodeToTree:      cloneMapContents(.NodeToTree),
		hubs:            captureExactSliceMap(.Hubs),
		sequencesRef:    .Sequences,
		sequences:       cloneMapContents(.Sequences),
		directionsRef:   .Directions,
		directions:      cloneMapContents(.Directions),
		commonSiblings:  captureExactSliceMap(.CommonUncleSiblings),
	}
}

// captureGeometryState records the fields changed by ordinary speculative
// placement transactions without walking and copying the graph's ownership
// maps. Topology-changing transactions additionally call captureRuntimeState.
func ( *GraphState) ( *Graph,  *limits.WorkGuard) error {
	if .captureEdgeRoutes {
		 := make(map[*Edge]struct{}, len(.Edges))
		for ,  := range .Edges {
			if  := .Step();  != nil {
				return 
			}
			if  == nil {
				return fmt.Errorf("TALA geometry snapshot contains a nil edge")
			}
			[] = struct{}{}
		}
		for  := range .nodeGeometry {
			if  := .Step();  != nil {
				return 
			}
			for ,  := range .Edges {
				if  := .Step();  != nil {
					return 
				}
				if  != nil {
					[] = struct{}{}
				}
			}
		}
		.edgeGeometry = make(map[*Edge]edgeSnapshot, len())
		for  := range  {
			if  := .Step();  != nil {
				return 
			}
			for range .Points[:cap(.Points)] {
				if  := .Step();  != nil {
					return 
				}
			}
			.edgeGeometry[] = captureEdge()
		}
	} else {
		.edgeGeometry = nil
	}

	.treeOrientations = make(map[*Tree]geo.Orientation, len(.NodeToTree))
	for ,  := range .NodeToTree {
		if  := .Step();  != nil {
			return 
		}
		if  != nil {
			.treeOrientations[] = .Orientation
		}
	}
	return .Finish()
}

func ( graphSnapshot) ( *Graph) {
	.IsRootHierarchy = .isRootHierarchy
	.Nodes = .nodes.restore()
	.Edges = .edges.restore()
	.CellSize = .cellSize
	.Containers = .containers.restore()
	.Clusters = restoreMap(.clustersRef, .clusters)
	.Trees = .trees.restore()
	.NodeToTree = restoreMap(.nodeToTreeRef, .nodeToTree)
	.Hubs = .hubs.restore()
	.Sequences = restoreMap(.sequencesRef, .sequences)
	.Directions = restoreMap(.directionsRef, .directions)
	.CommonUncleSiblings = .commonSiblings.restore()
}

type runtimeObjectCollection struct {
	nodes          map[*Node]struct{}
	nodeOrder      []*Node
	edges          map[*Edge]struct{}
	clusters       map[*Cluster]struct{}
	sequences      map[*Sequence]struct{}
	trees          map[*Tree]struct{}
	edgeAbductions map[*EdgeAbduction]struct{}
	herds          map[*HerdAssignment]struct{}
	hierarchies    map[*Hierarchy]struct{}
}

// collectRuntimeObjectsContext follows every reference that can keep mutable
// layout state alive outside Graph.Nodes. Both full transaction snapshots and
// narrower field snapshots use this one bounded traversal so their ownership
// coverage cannot drift apart.
func collectRuntimeObjectsContext( *Graph,  *limits.WorkGuard,  string) (runtimeObjectCollection, error) {
	 := make(map[*Node]struct{}, len(.Nodes))
	var  map[*Edge]struct{}
	var  map[*Cluster]struct{}
	var  map[*Sequence]struct{}
	var  map[*Tree]struct{}
	var  map[*EdgeAbduction]struct{}
	var  map[*HerdAssignment]struct{}
	var  map[*Hierarchy]struct{}

	var  []*Node
	var  []*Edge
	var  []*Cluster
	var  []*Sequence
	var  []*Tree
	var  []*EdgeAbduction
	var  []*HerdAssignment
	var  []*Hierarchy
	var  error
	 := func() bool {
		if  != nil {
			return false
		}
		 = .Step()
		return  == nil
	}

	 := func( *Node) {
		if !() {
			return
		}
		if  == nil {
			return
		}
		if ,  := [];  {
			return
		}
		if len() >= maxEngineNodes {
			 = fmt.Errorf("TALA %s node snapshot exceeds limit %d", , maxEngineNodes)
			return
		}
		[] = struct{}{}
		 = append(, )
	}
	 := func( *Edge) {
		if !() {
			return
		}
		if  == nil {
			return
		}
		if ,  := [];  {
			return
		}
		if len() >= maxEngineEdges {
			 = fmt.Errorf("TALA %s edge snapshot exceeds limit %d", , maxEngineEdges)
			return
		}
		if  == nil {
			 = make(map[*Edge]struct{})
		}
		[] = struct{}{}
		 = append(, )
	}
	 := func( *Cluster) {
		if !() {
			return
		}
		if  == nil {
			return
		}
		if ,  := [];  {
			return
		}
		if len() >= maxEngineNodes {
			 = fmt.Errorf("TALA %s cluster snapshot exceeds limit %d", , maxEngineNodes)
			return
		}
		if  == nil {
			 = make(map[*Cluster]struct{})
		}
		[] = struct{}{}
		 = append(, )
	}
	 := func( *Sequence) {
		if !() {
			return
		}
		if  == nil {
			return
		}
		if ,  := [];  {
			return
		}
		if len() >= maxEngineNodes {
			 = fmt.Errorf("TALA %s sequence snapshot exceeds limit %d", , maxEngineNodes)
			return
		}
		if  == nil {
			 = make(map[*Sequence]struct{})
		}
		[] = struct{}{}
		 = append(, )
	}
	 := func( *Tree) {
		if !() {
			return
		}
		if  == nil {
			return
		}
		if ,  := [];  {
			return
		}
		if len() >= maxEngineNodes {
			 = fmt.Errorf("TALA %s tree snapshot exceeds limit %d", , maxEngineNodes)
			return
		}
		if  == nil {
			 = make(map[*Tree]struct{})
		}
		[] = struct{}{}
		 = append(, )
	}
	 := func( *EdgeAbduction) {
		if !() {
			return
		}
		if  == nil {
			return
		}
		if ,  := [];  {
			return
		}
		if len() >= maxEngineEdges {
			 = fmt.Errorf("TALA %s edge-abduction snapshot exceeds limit %d", , maxEngineEdges)
			return
		}
		if  == nil {
			 = make(map[*EdgeAbduction]struct{})
		}
		[] = struct{}{}
		 = append(, )
	}
	 := func( *HerdAssignment) {
		if !() {
			return
		}
		if  == nil {
			return
		}
		if ,  := [];  {
			return
		}
		if len() >= maxEngineNodes {
			 = fmt.Errorf("TALA %s herd snapshot exceeds limit %d", , maxEngineNodes)
			return
		}
		if  == nil {
			 = make(map[*HerdAssignment]struct{})
		}
		[] = struct{}{}
		 = append(, )
	}
	 := func( *Hierarchy) {
		if !() {
			return
		}
		if  == nil {
			return
		}
		if ,  := [];  {
			return
		}
		if len() >= maxEngineNodes {
			 = fmt.Errorf("TALA %s hierarchy snapshot exceeds limit %d", , maxEngineNodes)
			return
		}
		if  == nil {
			 = make(map[*Hierarchy]struct{})
		}
		[] = struct{}{}
		 = append(, )
	}

	for ,  := range .Nodes {
		()
	}
	for ,  := range .Edges {
		()
	}
	for ,  := range .Containers {
		()
		for ,  := range  {
			()
		}
	}
	for ,  := range .Clusters {
		()
		()
	}
	for ,  := range .Sequences {
		()
		()
	}
	for ,  := range .Trees {
		()
		for ,  := range  {
			()
		}
	}
	for ,  := range .NodeToTree {
		()
		()
	}
	for ,  := range .Hubs {
		()
		for ,  := range  {
			()
		}
	}
	for ,  := range .CommonUncleSiblings {
		()
		for ,  := range  {
			()
		}
	}
	for  := range .Directions {
		()
	}
	if  != nil {
		return runtimeObjectCollection{}, 
	}

	var , , ,  int
	var , , ,  int
	for  < len() ||  < len() ||  < len() ||
		 < len() ||  < len() ||  < len() ||
		 < len() ||  < len() {
		if  != nil {
			return runtimeObjectCollection{}, 
		}
		switch {
		case  < len():
			 := []
			++
			(.Container)
			for  := range .Nears {
				()
			}
			for  := range .LongDistanceNeighborRequirements {
				()
			}
			for ,  := range .Edges {
				()
			}
			(.Cluster)
			(.Sequence)
			(.HerdAssignment)
			(.Hierarchy)

		case  < len():
			 := []
			++
			(.From)
			(.To)

		case  < len():
			 := []
			++
			(.Vessel)
			(.Container)
			for ,  := range .Nodes {
				()
			}
			for ,  := range .EdgeAbductions {
				()
			}

		case  < len():
			 := []
			++
			(.Vessel)
			(.Container)
			for ,  := range .Nodes {
				()
			}
			for ,  := range .EdgeAbductions {
				()
			}

		case  < len():
			 := []
			++
			(.Node)
			(.SentinelEdge)
			(.Parent)
			for ,  := range .Children {
				()
			}

		case  < len():
			 := []
			++
			(.Edge)
			(.OriginallyFrom)
			(.OriginallyTo)
			(.CurrentFrom)
			(.CurrentTo)

		case  < len():
			 := []
			++
			for  := range .oppositeSidePaired {
				()
			}
			for  := range .sameSidePaired {
				()
			}

		case  < len():
			 := []
			++
			for  := range .level {
				()
			}
		}
		if  != nil {
			return runtimeObjectCollection{}, 
		}
	}

	return runtimeObjectCollection{
		nodes:          ,
		nodeOrder:      ,
		edges:          ,
		clusters:       ,
		sequences:      ,
		trees:          ,
		edgeAbductions: ,
		herds:          ,
		hierarchies:    ,
	}, nil
}

func ( *GraphState) ( *Graph,  *limits.WorkGuard) error {
	,  := collectRuntimeObjectsContext(, , "transaction runtime")
	if  != nil {
		return 
	}
	 := .nodes
	 := .edges
	 := .clusters
	 := .sequences
	 := .trees
	 := .edgeAbductions
	 := .herds
	 := .hierarchies

	if  := .Step();  != nil {
		return 
	}
	.graph = captureGraph()
	.nodes = make(map[*Node]nodeSnapshot, len())
	for  := range  {
		if  := .Step();  != nil {
			return 
		}
		.nodes[] = captureNode()
	}
	.edges = make(map[*Edge]edgeSnapshot, len())
	for  := range  {
		if  := .Step();  != nil {
			return 
		}
		for range .Points[:cap(.Points)] {
			if  := .Step();  != nil {
				return 
			}
		}
		.edges[] = captureEdge()
	}
	.clusters = make(map[*Cluster]clusterSnapshot, len())
	for  := range  {
		if  := .Step();  != nil {
			return 
		}
		.clusters[] = clusterSnapshot{
			value:          *,
			nodes:          captureExactSlice(.Nodes),
			edgeAbductions: captureExactSlice(.EdgeAbductions),
		}
	}
	.sequences = make(map[*Sequence]sequenceSnapshot, len())
	for  := range  {
		if  := .Step();  != nil {
			return 
		}
		.sequences[] = sequenceSnapshot{
			value:          *,
			nodes:          captureExactSlice(.Nodes),
			edgeAbductions: captureExactSlice(.EdgeAbductions),
		}
	}
	.trees = make(map[*Tree]treeSnapshot, len())
	for  := range  {
		if  := .Step();  != nil {
			return 
		}
		.trees[] = treeSnapshot{value: *, children: captureExactSlice(.Children)}
	}
	.edgeAbductions = make(map[*EdgeAbduction]EdgeAbduction, len())
	for  := range  {
		if  := .Step();  != nil {
			return 
		}
		.edgeAbductions[] = *
	}
	.herds = make(map[*HerdAssignment]herdSnapshot, len())
	for  := range  {
		if  := .Step();  != nil {
			return 
		}
		.herds[] = herdSnapshot{
			value:              *,
			oppositeSidePaired: cloneMapContents(.oppositeSidePaired),
			sameSidePaired:     cloneMapContents(.sameSidePaired),
		}
	}
	.hierarchies = make(map[*Hierarchy]hierarchySnapshot, len())
	for  := range  {
		if  := .Step();  != nil {
			return 
		}
		.hierarchies[] = hierarchySnapshot{value: *, level: cloneMapContents(.level)}
	}
	return .Finish()
}