# Single-package reduction of #4367. A top-level field OUT instantiates a
# template TEMPLATE, whose body re-instantiates that same template through a
# comprehension over the IMPORTS data: `({cfg: _} & imp).export.objects`.
#
# Before the fix, OUT and the nested `export` both reference the shared
# TEMPLATE, and the cycle detector recorded OUT's resolution of TEMPLATE in
# the conjunct's Refs history. When `export` (reached via the IMPORTS data,
# a sibling branch of OUT, not a descendant) re-resolved TEMPLATE, the stale
# Refs entry made the detector report a spurious structural cycle. That cycle
# tainted the `cfg: string | *""` disjunction so its default reappeared as a
# concrete branch, yielding `cfg: conflicting values "" and "sub-"`.
#
# The fix recognizes the reoccurrence as structure sharing rather than
# recursion: `export` is reached through a distinct reference and still has
# non-cyclic conjuncts (a real definition body), so it is not a self-feeding
# cycle and is not marked cyclic. OUT must stay top-level: nesting it deeper
# shifts the evaluation depth and the existing depth-based escape masks the
# bug.
#
# https://cuelang.org/issue/4367
-- cue.mod/module.cue --
module: "example.com/m@v0"
language: version: "v0.12.0"
-- main.cue --
import "strings"

OUT: TEMPLATE & {
	IMPORTS: [{
		export: TEMPLATE & {
			OBJECTS: objects
			GENERATORS: [{
				IN: {}
				OUT: [if IN.spec != "" {}]
			}]
		}

		cfg: string | *""
		cfg: "sub-"

		objects: [string]: [string]: {
			spec: _
			metadata: name: cfg + {strings.ToUpper(spec)}
		}
		objects: plain: a: spec: objects.plain.b.metadata.name
		objects: plain: b: spec: "hashed"
	}]
}

TEMPLATE: {
	OBJECTS: {...}
	IMPORTS: [...]
	GENERATORS: [...]

	_localObjects: [
		for _, objs in OBJECTS
		for _, obj in objs {obj},
	]
	_generatedObjects: [
		for _, obj in _localObjects
		for _, gen in GENERATORS
		for _, o in (gen & {IN: obj}).OUT {o},
	]
	_importedObjects: [
		for _, imp in IMPORTS
		for _, obj in ({cfg: _} & imp).export.objects {obj},
	]
	objects: [
		for _, obj in _localObjects {obj},
		for _, obj in _generatedObjects {obj},
		for _, obj in _importedObjects {obj},
	]
}

// Before the fix these reported `cfg: conflicting values "" and "sub-"`.
checkCfg: OUT.IMPORTS[0].cfg @test(eq, "sub-")
checkName: OUT.IMPORTS[0].objects.plain.b.metadata.name @test(eq, "sub-HASHED")
-- out/errors.txt --
[incomplete] OUT.IMPORTS.0.export.GENERATORS.0.OUT: undefined field: spec:
    ./main.cue:9:17
-- out/eval/stats --
Leaks:  33
Freed:  175
Reused: 126
Allocs: 82
Retain: 0

Unifications: 175
Conjuncts:    398
Disjuncts:    4
Notifications: 14

NumCloseIDs: 161
