from __future__ import annotations

import json
from pathlib import Path

from jsonschema import Draft202012Validator
from referencing import Registry, Resource

ROOT = Path(__file__).resolve().parents[1]
SCHEMA_DIR = ROOT / "schemas"
EXAMPLE_DIR = ROOT / "examples"

PAIRS = [
    ("project-contract.schema.json", "project-contract.example.json"),
    ("case-input.schema.json", "case-input.example.json"),
    ("evaluation-output.schema.json", "evaluation-output.example.json"),
    ("benchmark-item.schema.json", "benchmark-item.example.json"),
    ("human-resolution-packet.schema.json", "human-resolution-packet.example.json"),
]


def load_json(path: Path):
    with path.open("r", encoding="utf-8") as handle:
        return json.load(handle)


def build_registry() -> Registry:
    registry = Registry()
    for schema_path in SCHEMA_DIR.glob("*.schema.json"):
        schema = load_json(schema_path)
        Draft202012Validator.check_schema(schema)
        schema_id = schema.get("$id")
        if not schema_id:
            raise ValueError(f"Schema has no $id: {schema_path}")
        registry = registry.with_resource(schema_id, Resource.from_contents(schema))
    return registry


def validate_examples() -> list[str]:
    registry = build_registry()
    failures: list[str] = []

    for schema_name, example_name in PAIRS:
        schema_path = SCHEMA_DIR / schema_name
        example_path = EXAMPLE_DIR / example_name
        schema = load_json(schema_path)
        instance = load_json(example_path)
        validator = Draft202012Validator(schema, registry=registry)
        errors = sorted(validator.iter_errors(instance), key=lambda e: list(e.absolute_path))
        if errors:
            failures.append(example_name)
            print(f"FAIL {example_name}")
            for error in errors:
                path = ".".join(str(part) for part in error.absolute_path) or "<root>"
                print(f"  {path}: {error.message}")
        else:
            print(f"PASS {example_name}")

    return failures


def main() -> None:
    failures = validate_examples()
    if failures:
        raise SystemExit(1)


if __name__ == "__main__":
    main()
