# CUE incorrectly reports a structural cycle error for a valid CUE expression
# that does not actually contain a cycle, producing a false positive.
# https://cuelang.org/issue/990
-- in.cue --
// A simple discriminated element
#AC: {
	k: "simple"
	d: #C
}

// A recursive discriminated element
#AS: {
	k: "complex"
	d: #S
}

#R: {
	a: #AC | #AS
}

// The structure of the recursive element
#S: {
	n: string
	r: [string]: #R
}

// The structure of the simple element
#C: {
	n: string
}

#sub: {
	$p=#p: #AS
	dict: [string]: _

	for rn, rd in $p.d.r if rd.a.k == "complex" {
		let subs = #sub & {#p: rd.a}
		for sn, sd in subs.dict {
			dict: "\(rn)_\(sn)": sd
		}
	}
	for rn, rd in $p.d.r if rd.a.k == "simple" {
		dict: "\(rn)": rd
	}
}

// Data
_test: {
	c1: #AC
	c1: d: {
		n: "c1"
	}


	s3: #AS
	s3: d: {
		n: "s3"
		r: r1: a:c1
	}

	s2: #AS
	s2: d: {
		n: "s2"
		r: {
			r1: a: c1
			r2: a: s3
		}
	}

	s1: #AS
	s1: d: {
		n: "s1"
		r: {
			r1: a: c1
			r2: a: s2
		}
	}
}

//  Test

out: #sub & {#p: _test.s1}

// TODO(fmt): can we improve this?
@test(eq, {
	#AC: {k: "simple", d: {n: string}}
	#AS: {k: "complex", d: {n: string, r: {}}}
	#R: {
		a: {k: "simple", d: {n: string}} | {k: "complex", d: {n: string, r: {}}}
	}
	#S: {n: string, r: {}}
	#C: {n: string}
	#sub: {
		#p: {k: "complex", d: {n: string, r: {}}}
		dict: {}
	}
	_test: {
		c1: {d: {n: "c1"}, k: "simple"}
		s3: {
			d: {
				n: "s3"
				r: {r1: {a: {d: {n: "c1"}, k: "simple"}}}
			}
			k: "complex"
		}
		s2: {
			d: {
				n: "s2"
				r: {
					r1: {a: {d: {n: "c1"}, k: "simple"}}
					r2: {
						a: {
							d: {
								n: "s3"
								r: {r1: {a: {d: {n: "c1"}, k: "simple"}}}
							}
							k: "complex"
						}
					}
				}
			}
			k: "complex"
		}
		s1: {
			d: {
				n: "s1"
				r: {
					r1: {a: {d: {n: "c1"}, k: "simple"}}
					r2: {
						a: {
							d: {
								n: "s2"
								r: {
									r1: {a: {d: {n: "c1"}, k: "simple"}}
									r2: {
										a: {
											d: {
												n: "s3"
												r: {r1: {a: {d: {n: "c1"}, k: "simple"}}}
											}
											k: "complex"
										}
									}
								}
							}
							k: "complex"
						}
					}
				}
			}
			k: "complex"
		}
	}
	out: {
		#p: {
			d: {
				n: "s1"
				r: {
					r1: {a: {d: {n: "c1"}, k: "simple"}}
					r2: {
						a: {
							d: {
								n: "s2"
								r: {
									r1: {a: {d: {n: "c1"}, k: "simple"}}
									r2: {
										a: {
											d: {
												n: "s3"
												r: {r1: {a: {d: {n: "c1"}, k: "simple"}}}
											}
											k: "complex"
										}
									}
								}
							}
							k: "complex"
						}
					}
				}
			}
			k: "complex"
		}
		dict: {
			r1: {a: {d: {n: "c1"}, k: "simple"}}
			r2_r1: {a: {d: {n: "c1"}, k: "simple"}}
			r2_r2_r1: {a: {d: {n: "c1"}, k: "simple"}}
		}
	}
})
-- out/eval/stats --
Leaks:  197
Freed:  664
Reused: 635
Allocs: 226
Retain: 0

Unifications: 330
Conjuncts:    1367
Disjuncts:    106

NumCloseIDs: 428

ConjunctInfos:       1003
MaxConjunctInfos:    6
MaxReqSets:          19
MaxRedirect:         4
