"""Phase 3 — Contract enforcement tightening for abi-evals.

Validates eval results against expected schema structure.
abi-core schemas are read-only references.
"""

from __future__ import annotations

import json

import pytest

from abi_evals.runner import run_suite


class TestEvalResultStructuralCompliance:
    """Eval results conform to eval-result/1.0 structure."""

    def test_top_level_keys(self, sample_suite):
        result = run_suite(sample_suite, run_id="ct000001", timestamp="2025-01-01T00:00:00Z")
        required = {"schema_version", "suite_id", "run_id", "evaluated_at", "results", "summary"}
        assert required.issubset(result.keys()), f"Missing keys: {required - result.keys()}"

    def test_schema_version_value(self, sample_suite):
        result = run_suite(sample_suite, run_id="ct000001", timestamp="2025-01-01T00:00:00Z")
        assert result["schema_version"] == "eval-result/1.0"

    def test_results_is_array(self, sample_suite):
        result = run_suite(sample_suite, run_id="ct000001", timestamp="2025-01-01T00:00:00Z")
        assert isinstance(result["results"], list)

    def test_summary_counts_match(self, sample_suite):
        result = run_suite(sample_suite, run_id="ct000001", timestamp="2025-01-01T00:00:00Z")
        s = result["summary"]
        actual_statuses = [r["status"] for r in result["results"]]
        assert s["total"] == len(actual_statuses)
        assert s["passed"] == actual_statuses.count("pass")
        assert s["failed"] == actual_statuses.count("fail")
        assert s["errors"] == actual_statuses.count("error")

    def test_malformed_suite_rejected(self):
        """Suite without suite_id raises ValueError."""
        import tempfile
        from pathlib import Path

        from abi_evals.runner import load_eval_suite  # noqa: E402

        with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as f:
            json.dump({"cases": [{"case_id": "tc-1"}]}, f)
            f.flush()
            with pytest.raises(ValueError, match="suite_id"):
                load_eval_suite(Path(f.name))
