# Tests that recursive schema definitions with many optional fields (e.g. a
# JSON-Schema-like #Schema with properties/required) do not cause exponential
# conjunct blowup when embedded or unified. The `reduced` case validates basic
# self-embedding; `full` validates a realistic JSON-Schema-style structure.
# https://cuelang.org/issue/3633
-- in.cue --
reduced: {
	#Schema: {
		a?: null | bool | string | int | #Schema
		b?: null | bool | string | int | #Schema
		c?: null | bool | string | int | #Schema
		d?: null | bool | string | int | #Schema
		e?: null | bool | string | int | #Schema
		f?: null | bool | string | int | #Schema
	}

	out: #Schema & {#Schema}
}
full: {
	#Schema: {
		required?: [...string]
		properties?: [string]: null | bool | string | [...int] | #Schema

		foo00?: null | bool | string | [...int] | {string: int32}
		foo01?: null | bool | string | [...int] | {string: int32}
		foo02?: null | bool | string | [...int] | {string: int32}
		foo03?: null | bool | string | [...int] | {string: int32}
		foo04?: null | bool | string | [...int] | {string: int32}
		foo05?: null | bool | string | [...int] | {string: int32}
		foo06?: null | bool | string | [...int] | {string: int32}
		foo07?: null | bool | string | [...int] | {string: int32}
		foo08?: null | bool | string | [...int] | {string: int32}
		foo09?: null | bool | string | [...int] | {string: int32}
		foo10?: null | bool | string | [...int] | {string: int32}
		foo11?: null | bool | string | [...int] | {string: int32}
		foo12?: null | bool | string | [...int] | {string: int32}
		foo13?: null | bool | string | [...int] | {string: int32}
		foo14?: null | bool | string | [...int] | {string: int32}
		foo15?: null | bool | string | [...int] | {string: int32}
		foo16?: null | bool | string | [...int] | {string: int32}
		foo17?: null | bool | string | [...int] | {string: int32}
		foo18?: null | bool | string | [...int] | {string: int32}
		foo19?: null | bool | string | [...int] | {string: int32}
	}

	out: [...#Schema] & [{
		#Schema
		properties: foo: required: ["bar", "baz"]
	}]
}
-- out/compile --
--- in.cue
{
  reduced: {
    #Schema: {
      a?: (null|bool|string|int|〈1;#Schema〉)
      b?: (null|bool|string|int|〈1;#Schema〉)
      c?: (null|bool|string|int|〈1;#Schema〉)
      d?: (null|bool|string|int|〈1;#Schema〉)
      e?: (null|bool|string|int|〈1;#Schema〉)
      f?: (null|bool|string|int|〈1;#Schema〉)
    }
    out: (〈0;#Schema〉 & {
      〈1;#Schema〉
    })
  }
  full: {
    #Schema: {
      required?: [
        ...string,
      ]
      properties?: {
        [string]: (null|bool|string|[
          ...int,
        ]|〈2;#Schema〉)
      }
      foo00?: (null|bool|string|[
        ...int,
      ]|{
        string: &(int, >=-2147483648, <=2147483647)
      })
      foo01?: (null|bool|string|[
        ...int,
      ]|{
        string: &(int, >=-2147483648, <=2147483647)
      })
      foo02?: (null|bool|string|[
        ...int,
      ]|{
        string: &(int, >=-2147483648, <=2147483647)
      })
      foo03?: (null|bool|string|[
        ...int,
      ]|{
        string: &(int, >=-2147483648, <=2147483647)
      })
      foo04?: (null|bool|string|[
        ...int,
      ]|{
        string: &(int, >=-2147483648, <=2147483647)
      })
      foo05?: (null|bool|string|[
        ...int,
      ]|{
        string: &(int, >=-2147483648, <=2147483647)
      })
      foo06?: (null|bool|string|[
        ...int,
      ]|{
        string: &(int, >=-2147483648, <=2147483647)
      })
      foo07?: (null|bool|string|[
        ...int,
      ]|{
        string: &(int, >=-2147483648, <=2147483647)
      })
      foo08?: (null|bool|string|[
        ...int,
      ]|{
        string: &(int, >=-2147483648, <=2147483647)
      })
      foo09?: (null|bool|string|[
        ...int,
      ]|{
        string: &(int, >=-2147483648, <=2147483647)
      })
      foo10?: (null|bool|string|[
        ...int,
      ]|{
        string: &(int, >=-2147483648, <=2147483647)
      })
      foo11?: (null|bool|string|[
        ...int,
      ]|{
        string: &(int, >=-2147483648, <=2147483647)
      })
      foo12?: (null|bool|string|[
        ...int,
      ]|{
        string: &(int, >=-2147483648, <=2147483647)
      })
      foo13?: (null|bool|string|[
        ...int,
      ]|{
        string: &(int, >=-2147483648, <=2147483647)
      })
      foo14?: (null|bool|string|[
        ...int,
      ]|{
        string: &(int, >=-2147483648, <=2147483647)
      })
      foo15?: (null|bool|string|[
        ...int,
      ]|{
        string: &(int, >=-2147483648, <=2147483647)
      })
      foo16?: (null|bool|string|[
        ...int,
      ]|{
        string: &(int, >=-2147483648, <=2147483647)
      })
      foo17?: (null|bool|string|[
        ...int,
      ]|{
        string: &(int, >=-2147483648, <=2147483647)
      })
      foo18?: (null|bool|string|[
        ...int,
      ]|{
        string: &(int, >=-2147483648, <=2147483647)
      })
      foo19?: (null|bool|string|[
        ...int,
      ]|{
        string: &(int, >=-2147483648, <=2147483647)
      })
    }
    out: ([
      ...〈1;#Schema〉,
    ] & [
      {
        〈2;#Schema〉
        properties: {
          foo: {
            required: [
              "bar",
              "baz",
            ]
          }
        }
      },
    ])
  }
}
