{
	"$schema": "https://json-schema.org/draft/2020-12/schema",
	"title": "Alef E2E Test Fixture",
	"description": "Schema for alef e2e test fixture files. Each file contains either a single fixture object or an array of fixtures.",
	"oneOf": [{ "$ref": "#/$defs/fixture" }, { "type": "array", "items": { "$ref": "#/$defs/fixture" } }],
	"$defs": {
		"fixture": {
			"type": "object",
			"required": ["id", "description"],
			"additionalProperties": false,
			"properties": {
				"id": {
					"type": "string",
					"pattern": "^[a-z][a-z0-9_]*$",
					"description": "Unique snake_case identifier used as the test function name"
				},
				"category": {
					"type": "string",
					"description": "Test category. Defaults to parent directory name if omitted"
				},
				"description": { "type": "string", "description": "Human-readable test description" },
				"tags": {
					"type": "array",
					"items": { "type": "string" },
					"description": "Optional tags for filtering"
				},
				"skip": { "$ref": "#/$defs/skip" },
				"env": { "$ref": "#/$defs/env" },
				"setup": {
					"type": "array",
					"items": { "$ref": "#/$defs/setup_call" },
					"description": "Setup calls executed before the main call"
				},
				"call": {
					"type": "string",
					"description": "Named call config to use. References [e2e.calls.<name>]. Defaults to [e2e.call] when omitted"
				},
				"input": {
					"type": "object",
					"description": "Input data passed to the function under test. Fields map to args via [e2e.call.args] config"
				},
				"config": {
					"description": "Optional fixture-level config mirrored into input.config before code generation"
				},
				"mock_response": { "$ref": "#/$defs/mock_response" },
				"visitor": {
					"type": "object",
					"description": "Visitor callback specification for visitor-pattern tests"
				},
				"args": {
					"type": "array",
					"items": { "$ref": "#/$defs/arg_mapping" },
					"description": "Fixture-level argument mappings. When present, overrides the resolved call args"
				},
				"assertion_recipes": {
					"type": "array",
					"items": { "type": "string" },
					"description": "Assertion recipes enabled for domain-shaped assertion shortcuts and streaming pseudo-fields"
				},
				"assertions": {
					"type": "array",
					"items": { "$ref": "#/$defs/assertion" },
					"description": "List of assertions to check on the result"
				},
				"http": {
					"type": "object",
					"description": "HTTP server fixture specification"
				}
			}
		},
		"env": {
			"type": "object",
			"additionalProperties": false,
			"properties": {
				"api_key_var": { "type": "string" }
			}
		},
		"setup_call": {
			"type": "object",
			"required": ["call"],
			"additionalProperties": false,
			"properties": {
				"call": { "type": "string" },
				"input": {}
			}
		},
		"mock_response": {
			"type": "object",
			"required": ["status"],
			"additionalProperties": false,
			"properties": {
				"status": { "type": "integer", "minimum": 100, "maximum": 599 },
				"body": {},
				"stream_chunks": {
					"type": "array",
					"items": {}
				},
				"headers": {
					"type": "object",
					"additionalProperties": { "type": "string" }
				}
			}
		},
		"arg_mapping": {
			"type": "object",
			"required": ["name", "field"],
			"additionalProperties": false,
			"properties": {
				"name": { "type": "string" },
				"field": { "type": "string" },
				"type": { "type": "string" },
				"arg_type": { "type": "string" },
				"optional": { "type": "boolean" },
				"owned": { "type": "boolean" },
				"element_type": { "type": "string" },
				"go_type": { "type": "string" },
				"vec_inner_is_ref": { "type": "boolean" },
				"trait_name": { "type": "string" },
				"trait": { "type": "string" }
			}
		},
		"skip": {
			"type": "object",
			"additionalProperties": false,
			"properties": {
				"languages": {
					"type": "array",
					"items": { "type": "string" },
					"description": "Languages to skip. Empty array means skip all"
				},
				"reason": { "type": "string", "description": "Human-readable reason for skipping" }
			}
		},
		"assertion": {
			"type": "object",
			"required": ["type"],
			"additionalProperties": false,
			"properties": {
				"type": {
					"type": "string",
					"enum": [
						"not_error",
						"error",
						"equals",
						"not_equals",
						"contains",
						"contains_all",
						"contains_any",
						"not_contains",
						"not_empty",
						"is_empty",
						"starts_with",
						"ends_with",
						"min_length",
						"max_length",
						"count_min",
						"count_equals",
						"matches_regex",
						"is_true",
						"is_false",
						"greater_than",
						"less_than",
						"greater_than_or_equal",
						"less_than_or_equal",
						"method_result"
					],
					"description": "Assertion type"
				},
				"field": {
					"type": "string",
					"description": "Dot-separated field path on the result object"
				},
				"value": { "description": "Expected value (type depends on assertion type)" },
				"values": {
					"type": "array",
					"description": "Expected values (for contains_all, contains_any, not_contains)"
				},
				"method": { "type": "string", "description": "Method name to call on the result" },
				"check": {
					"type": "string",
					"description": "Assertion check type for the method result (equals, is_true, is_false, greater_than_or_equal, count_min)"
				},
				"args": { "description": "Arguments to pass to the method call" },
				"return_type": {
					"type": "string",
					"description": "Return type hint for generated assertion code"
				}
			}
		}
	}
}
