# Some new cases specific to v0.7
-- builtins.cue --
import "strings"

mutualBuiltin: t1: ok: {
	// Results in incomplete error in v0.6
	s3: strings.ContainsAny(s4)
	s4: strings.ContainsAny(s3)
	s4: "dd"
}

mutualBuiltin: t2: ok: {
	s3: strings.ContainsAny(s5, "dd")
	s5: s6
	s6: "dd"
}
-- comprehensions.cue --
comprehensions: t1: ok: {
	src: ["foo"]
	for v in src {"\(v)": v}
}
-- dynamic.cue --
dynamic: t1: ok: {
	[X=string]: {name: X}
	(x.y): {}
	x: y: "foo"
}

dynamic: t2: ok: {
	foo: #X
	#X: {
		a: b: C: 1
		for _ in a {
			a: ("b"): D: 2
		}
	}
}
-- definition.cue --
definition: t0: err: {
	#D1: env: {}
	d1: env: c: "C"
	d1: #D1
}

definition: t1: err: {
	a: #A
	a: c: 1
	// defining after first reference triggers notification mechanism to kick in.
	#A: {}
}

definition: t2: ok: p1: {
	#A: {
		...
		{a: int}
	}
	x: #A & {c: int}
}

definition: t2: ok: p2: {
	#A: {
		{a: int}
		...
	}
	x: #A & {c: int}
}

definition: t2: ok: p3: {
	x: #A & {c: int}
	#A: {
		...
		{a: int}
	}
}

definition: t2: ok: p4: {
	x: #A & {c: int}
	#A: {
		{a: int}
		...
	}
}
-- expr.cue --
expr: t1: ok: {
	a: X
	X: 5.0
	X: Y / 2
	Y: a * 2
}

expr: t2: ok: {
	A: X + 2
	X: 5
	X: A - 2
}

expr: t3: ok: p1: {
	a0: X
	X:  5.0
	X:  a0 * 1
}

expr: t3: ok: p2: {
	b: Y * 1
	Y: b * 1
	Y: 5.0
}

expr: t4: ok: {
	// -> a0 -> X -> b1 -> b0 -> a1 -> a0
	a0: X // Need all conjuncts known from X
	b0: a1
	a1: a0 + 2
	b1: b0 - 2
	a0: X // defined earlier
	X:  b1
	X:  5.0
}
-- in.cue --
mutual: t0: ok: {
	c: e & {b: 2}
	e: {a: 1}
	e: c
}

mutual: t1: ok: {
	a: {
		b
		b: {b: f: 1}
	}
	a: a.b
	a: b: {b: f: 1}
}

mutual: t2: ok: {
	x: a: a: f: 1
	x: y.a
	y: a: a: e: 1
	y: x.a
}

mutual: t3: ok: {
	d: e: f: 1
	d
	d: d: e: g: 1
}

// This test fails for some permutations in v0.6.
mutual: t4: ok: {
	p0: {
		z: x.b
		x: b: y.c
		x: b: {d: b: 2}
		y: c: z.d
		z: d: {a: 1}
	}

	p1: {
		x: b: y.c
		z: x.b
		x: b: {d: b: 2}
		y: c: z.d
		z: d: {a: 1}
	}

	p2: {
		x: b: y.c
		x: b: {d: b: 2}
		y: c: z.d
		z: x.b
		z: d: {a: 1}
	}

	p3: {
		x: b: {d: b: 2}
		y: c: z.d
		z: x.b
		x: b: y.c
		z: d: {a: 1}
	}

	p4: {
		z: x.b
		x: b: {d: b: 2}
		y: c: z.d
		x: b: y.c
		z: d: {a: 1}
	}

	p5: {
		x: b: {d: b: 2}
		y: c: z.d
		x: b: y.c
		z: x.b
		z: d: {a: 1}
	}

	check: p1 & p2 & p3 & p4 & p5
}
-- equality.cue --
// evalv3 nil pointer dereference panic in equalTerminal with repeated
// unifications of the same default disjunction inside a close() call.
// https://cuelang.org/issue/3194
issue3194: reduced: {
	A: *0 | >10
	A: *0 | >10
	{
		out: close({b: A})
		out: b: A
	}.out
}
-- chained.cue --
import "encoding/yaml"

// evalv3 "field set was already referenced" regression when a chained field
// lookup resolves through a dynamic field to a yaml.Marshal call.
// https://cuelang.org/issue/3925
issue3925: reduced: {
	out: yaml.Marshal(in.b.actual)
	in: {
		a: "actual"
		a: "actual" | "other"
		b: (a): c: "str"
	}
}
issue3925: full: {
	for name, _ in _inputs {
		out: (name): early: "early value"
	}
	_inputs: input1: {
		name: "actual"
		config: (name): one: "one value"
	}
	_inputs: [_]: {
		name: "actual" | "other"
	}
	for name, input in _inputs {
		out: (name): lateYAML: yaml.Marshal(input.config[input.name])
	}
}
-- out/compile --
--- builtins.cue
{
  mutualBuiltin: {
    t1: {
      ok: {
        s3: 〈import;strings〉.ContainsAny(〈0;s4〉)
        s4: 〈import;strings〉.ContainsAny(〈0;s3〉)
        s4: "dd"
      }
    }
  }
  mutualBuiltin: {
    t2: {
      ok: {
        s3: 〈import;strings〉.ContainsAny(〈0;s5〉, "dd")
        s5: 〈0;s6〉
        s6: "dd"
      }
    }
  }
}
--- chained.cue
{
  issue3925: {
    reduced: {
      out: 〈import;"encoding/yaml"〉.Marshal(〈0;in〉.b.actual)
      in: {
        a: "actual"
        a: ("actual"|"other")
        b: {
          〈1;a〉: {
            c: "str"
          }
        }
      }
    }
  }
  issue3925: {
    full: {
      for name, _ in 〈0;_inputs〉 {
        out: {
          〈2;name〉: {
            early: "early value"
          }
        }
      }
      _inputs: {
        input1: {
          name: "actual"
          config: {
            〈1;name〉: {
              one: "one value"
            }
          }
        }
      }
      _inputs: {
        [_]: {
          name: ("actual"|"other")
        }
      }
      for name, input in 〈0;_inputs〉 {
        out: {
          〈2;name〉: {
            lateYAML: 〈import;"encoding/yaml"〉.Marshal(〈3;input〉.config[〈3;input〉.name])
          }
        }
      }
    }
  }
}
--- comprehensions.cue
{
  comprehensions: {
    t1: {
      ok: {
        src: [
          "foo",
        ]
        for _, v in 〈0;src〉 {
          "\(〈1;v〉)": 〈1;v〉
        }
      }
    }
  }
}
--- definition.cue
{
  definition: {
    t0: {
      err: {
        #D1: {
          env: {}
        }
        d1: {
          env: {
            c: "C"
          }
        }
        d1: 〈0;#D1〉
      }
    }
  }
  definition: {
    t1: {
      err: {
        a: 〈0;#A〉
        a: {
          c: 1
        }
        #A: {}
      }
    }
  }
  definition: {
    t2: {
      ok: {
        p1: {
          #A: {
            ...
            {
              a: int
            }
          }
          x: (〈0;#A〉 & {
            c: int
          })
        }
      }
    }
  }
  definition: {
    t2: {
      ok: {
        p2: {
          #A: {
            {
              a: int
            }
            ...
          }
          x: (〈0;#A〉 & {
            c: int
          })
        }
      }
    }
  }
  definition: {
    t2: {
      ok: {
        p3: {
          x: (〈0;#A〉 & {
            c: int
          })
          #A: {
            ...
            {
              a: int
            }
          }
        }
      }
    }
  }
  definition: {
    t2: {
      ok: {
        p4: {
          x: (〈0;#A〉 & {
            c: int
          })
          #A: {
            {
              a: int
            }
            ...
          }
        }
      }
    }
  }
}
--- dynamic.cue
{
  dynamic: {
    t1: {
      ok: {
        [string]: {
          name: 〈1;-〉
        }
        〈0;x〉.y: {}
        x: {
          y: "foo"
        }
      }
    }
  }
  dynamic: {
    t2: {
      ok: {
        foo: 〈0;#X〉
        #X: {
          a: {
            b: {
              C: 1
            }
          }
          for _, _ in 〈0;a〉 {
            a: {
              "b": {
                D: 2
              }
            }
          }
        }
      }
    }
  }
}
--- equality.cue
{
  issue3194: {
    reduced: {
      A: (*0|>10)
      A: (*0|>10)
      {
        out: close({
          b: 〈2;A〉
        })
        out: {
          b: 〈2;A〉
        }
      }.out
    }
  }
}
--- expr.cue
{
  expr: {
    t1: {
      ok: {
        a: 〈0;X〉
        X: 5.0
        X: (〈0;Y〉 / 2)
        Y: (〈0;a〉 * 2)
      }
    }
  }
  expr: {
    t2: {
      ok: {
        A: (〈0;X〉 + 2)
        X: 5
        X: (〈0;A〉 - 2)
      }
    }
  }
  expr: {
    t3: {
      ok: {
        p1: {
          a0: 〈0;X〉
          X: 5.0
          X: (〈0;a0〉 * 1)
        }
      }
    }
  }
  expr: {
    t3: {
      ok: {
        p2: {
          b: (〈0;Y〉 * 1)
          Y: (〈0;b〉 * 1)
          Y: 5.0
        }
      }
    }
  }
  expr: {
    t4: {
      ok: {
        a0: 〈0;X〉
        b0: 〈0;a1〉
        a1: (〈0;a0〉 + 2)
        b1: (〈0;b0〉 - 2)
        a0: 〈0;X〉
        X: 〈0;b1〉
        X: 5.0
      }
    }
  }
}
--- in.cue
{
  mutual: {
    t0: {
      ok: {
        c: (〈0;e〉 & {
          b: 2
        })
        e: {
          a: 1
        }
        e: 〈0;c〉
      }
    }
  }
  mutual: {
    t1: {
      ok: {
        a: {
          〈0;b〉
          b: {
            b: {
              f: 1
            }
          }
        }
        a: 〈0;a〉.b
        a: {
          b: {
            b: {
              f: 1
            }
          }
        }
      }
    }
  }
  mutual: {
    t2: {
      ok: {
        x: {
          a: {
            a: {
              f: 1
            }
          }
        }
        x: 〈0;y〉.a
        y: {
          a: {
            a: {
              e: 1
            }
          }
        }
        y: 〈0;x〉.a
      }
    }
  }
  mutual: {
    t3: {
      ok: {
        d: {
          e: {
            f: 1
          }
        }
        〈0;d〉
        d: {
          d: {
            e: {
              g: 1
            }
          }
        }
      }
    }
  }
  mutual: {
    t4: {
      ok: {
        p0: {
          z: 〈0;x〉.b
          x: {
            b: 〈1;y〉.c
          }
          x: {
            b: {
              d: {
                b: 2
              }
            }
          }
          y: {
            c: 〈1;z〉.d
          }
          z: {
            d: {
              a: 1
            }
          }
        }
        p1: {
          x: {
            b: 〈1;y〉.c
          }
          z: 〈0;x〉.b
          x: {
            b: {
              d: {
                b: 2
              }
            }
          }
          y: {
            c: 〈1;z〉.d
          }
          z: {
            d: {
              a: 1
            }
          }
        }
        p2: {
          x: {
            b: 〈1;y〉.c
          }
          x: {
            b: {
              d: {
                b: 2
              }
            }
          }
          y: {
            c: 〈1;z〉.d
          }
          z: 〈0;x〉.b
          z: {
            d: {
              a: 1
            }
          }
        }
        p3: {
          x: {
            b: {
              d: {
                b: 2
              }
            }
          }
          y: {
            c: 〈1;z〉.d
          }
          z: 〈0;x〉.b
          x: {
            b: 〈1;y〉.c
          }
          z: {
            d: {
              a: 1
            }
          }
        }
        p4: {
          z: 〈0;x〉.b
          x: {
            b: {
              d: {
                b: 2
              }
            }
          }
          y: {
            c: 〈1;z〉.d
          }
          x: {
            b: 〈1;y〉.c
          }
          z: {
            d: {
              a: 1
            }
          }
        }
        p5: {
          x: {
            b: {
              d: {
                b: 2
              }
            }
          }
          y: {
            c: 〈1;z〉.d
          }
          x: {
            b: 〈1;y〉.c
          }
          z: 〈0;x〉.b
          z: {
            d: {
              a: 1
            }
          }
        }
        check: ((((〈0;p1〉 & 〈0;p2〉) & 〈0;p3〉) & 〈0;p4〉) & 〈0;p5〉)
      }
    }
  }
}
