-- test.cue --
package test

// matchN patterns generated by Extract
// These test the reverse transformation in Generate

// matchN(1, [...]) -> oneOf
oneOfTest?: matchN(1, [int, string, >5])

// matchN(0, [x]) -> not
notTest?: matchN(0, [int])

// matchN(>=1, [...]) -> anyOf
anyOfTest?: matchN(>=1, [int, string, bool])

// matchN(N, [...]) where N == len -> allOf
allOfTest?: matchN(3, [int, >5, <100])

// Edge cases
singleOneOf?: matchN(1, [string])
singleNot?: matchN(0, [bool])
singleAnyOf?: matchN(>=1, [int])
singleAllOf?: matchN(1, [int])

// Combined with other constraints
complexOneOf?: matchN(1, [int & >0, string & =~"^[a-z]+$", bool]) & !=null
complexAnyOf?: matchN(>=1, [int, string]) & !=5

-- datatest/tests.cue --
package datatest

ok1: data: {
	oneOfTest: 1
	notTest: "not an int"
	anyOfTest: true
	allOfTest: 10
	singleOneOf: "hello"
	singleNot: 123
	singleAnyOf: 42
	singleAllOf: 7
	complexOneOf: true
	complexAnyOf: "test"
}

ok2: data: {}

oneOfMultipleMatch: {
	data: oneOfTest: 7
	error: true
}

notMatch: {
	data: notTest: 5
	error: true
}

allOfNotMatch: {
	data: allOfTest: 200
	error: true
}

-- out/generate-v3/schema --
{
	$schema:     "https://json-schema.org/draft/2020-12/schema"
	type:        "object"
	description: "matchN patterns generated by Extract\nThese test the reverse transformation in Generate"
	properties: {
		allOfTest: {
			description: "matchN(N, [...]) where N == len -> allOf"
			allOf: [{
				type: "number"
			}, {
				type:             "integer"
				exclusiveMaximum: 100
				exclusiveMinimum: 5
			}]
		}
		anyOfTest: {
			description: "matchN(>=1, [...]) -> anyOf"
			anyOf: [{
				type: "integer"
			}, {
				type: "string"
			}, {
				type: "boolean"
			}]
		}
		complexAnyOf: {
			anyOf: [{
				type: "integer"
			}, {
				type: "string"
			}]
			not: {
				const: 5
			}
		}
		complexOneOf: {
			description: "Combined with other constraints"
			not: {
				const: null
			}
			oneOf: [{
				allOf: [{
					type: "number"
				}, {
					type:             "integer"
					exclusiveMinimum: 0
				}]
			}, {
				type:    "string"
				pattern: "^[a-z]+$"
			}, {
				type: "boolean"
			}]
		}
		notTest: {
			description: "matchN(0, [x]) -> not"
			not: {
				type: "integer"
			}
		}
		oneOfTest: {
			description: "matchN(1, [...]) -> oneOf"
			oneOf: [{
				type: "integer"
			}, {
				type: "string"
			}, {
				type:             "number"
				exclusiveMinimum: 5
			}]
		}
		singleAllOf: {
			oneOf: [{
				type: "integer"
			}]
		}
		singleAnyOf: {
			anyOf: [{
				type: "integer"
			}]
		}
		singleNot: {
			not: {
				type: "boolean"
			}
		}
		singleOneOf: {
			description: "Edge cases"
			oneOf: [{
				type: "string"
			}]
		}
	}
}
-- out/generate-v3/ok1 --
-- out/generate-v3/ok2 --
-- out/generate-v3/oneOfMultipleMatch --
oneOfMultipleMatch.data.oneOfTest: conflicting values 7 and string (mismatched types int and string):
    ./datatest/tests.cue:19:19
oneOfMultipleMatch.data.oneOfTest: invalid value 7 (does not satisfy matchN): 2 matched, expected 1:
    1:915
    ./datatest/tests.cue:19:19
-- out/generate-v3/notMatch --
notMatch.data.notTest: invalid value 5 (does not satisfy matchN): 1 matched, expected 0:
    1:834
    ./datatest/tests.cue:24:17
-- out/generate-v3/allOfNotMatch --
allOfNotMatch.data.allOfTest: invalid value 200 (out of bound <100):
    1:308
    ./datatest/tests.cue:29:19
