"""
Tests for perfect_cuboid.epistemic — Epistemic grading.

Tests framework patterns:
  AX43: Station = İstidlal
  AX44/T15: Külliyat > Tafsîlât (structural > detail)
  AX56: Max grade = İlmelyakîn
  AX57: Transparency disclosure
  KV₄: Convergence < 1
"""

import pytest

from perfect_cuboid.epistemic import (
    EpistemicGrade,
    ClaimType,
    GradedClaim,
    grade_cuboid_claims,
    epistemic_summary,
)


class TestEpistemicGrades:
    """AX56 — Grade hierarchy."""

    def test_no_hakkalyakin(self):
        """AX56: Hakkalyakîn is inaccessible — not defined in enum."""
        values = {g.value for g in EpistemicGrade}
        assert "hakkalyakin" not in values

    def test_three_accessible_grades(self):
        values = {g.value for g in EpistemicGrade}
        assert values == {"tasavvur", "tasdik", "ilmelyakin"}


class TestGradedClaims:
    """AX57 — Transparency + KV₄ — Convergence bound."""

    def test_all_claims_have_confidence_lt_1(self):
        """KV₄: No claim's confidence reaches 1.0."""
        claims = grade_cuboid_claims()
        for c in claims:
            assert c.confidence < 1.0, f"KV₄ violated: {c.statement[:40]}"

    def test_all_claims_have_confidence_gt_0(self):
        """KV₄: No claim's confidence is zero."""
        claims = grade_cuboid_claims()
        for c in claims:
            assert c.confidence > 0, f"KV₄ violated: {c.statement[:40]}"

    def test_no_claim_exceeds_ilmelyakin(self):
        """AX56: Maximum grade is İlmelyakîn."""
        claims = grade_cuboid_claims()
        for c in claims:
            assert c.grade in (EpistemicGrade.TASAVVUR,
                               EpistemicGrade.TASDIK,
                               EpistemicGrade.ILMELYAKIN)

    def test_claims_have_lens_disclosure(self):
        """AX57: Every claim discloses lenses used AND missing."""
        claims = grade_cuboid_claims()
        for c in claims:
            assert len(c.lenses_used) > 0, f"No lenses: {c.statement[:40]}"
            # lenses_missing can be empty in principle, but for our
            # bounded analysis it should always have entries
            assert len(c.lenses_missing) > 0 or len(c.lenses_used) == 7

    def test_claims_have_caveats(self):
        """AX57: Every claim has at least one caveat."""
        claims = grade_cuboid_claims()
        for c in claims:
            assert len(c.caveats) > 0, f"No caveats: {c.statement[:40]}"

    def test_kv4_boundary_flagged(self):
        """KV₄: Any claim with confidence ≥ 0.95 should have an explicit caveat."""
        claims = grade_cuboid_claims()
        boundary_claims = [c for c in claims if c.confidence >= 0.95]
        for c in boundary_claims:
            # Should mention KV₄ or boundary in caveats
            caveat_text = " ".join(c.caveats).lower()
            assert "kv" in caveat_text or "boundary" in caveat_text, \
                f"KV₄ boundary not flagged for: {c.statement[:40]}"


class TestT15ConvergenceGradient:
    """T15 — Structural claims more reliable than detail claims."""

    def test_structural_confidence_exceeds_detail(self):
        """T15: avg(külliyat confidence) > avg(tafsîlât confidence)."""
        summary = epistemic_summary()
        assert summary["t15_verified"] is True

    def test_structural_claims_exist(self):
        summary = epistemic_summary()
        assert summary["structural_claims"] > 0

    def test_detail_claims_exist(self):
        summary = epistemic_summary()
        assert summary["detail_claims"] > 0


class TestEpistemicSummary:
    """AX57 — Full transparency report."""

    def test_station_is_istidlal(self):
        """AX43: Our station is İstidlal."""
        summary = epistemic_summary()
        assert "istidlal" in summary["station"].lower()

    def test_multiple_lenses_engaged(self):
        """T16: Single-faculty is insufficient — need multiple."""
        summary = epistemic_summary()
        assert len(summary["lenses_engaged"]) >= 3

    def test_max_grade_is_ilmelyakin(self):
        """AX56: Max achieved grade is İlmelyakîn."""
        summary = epistemic_summary()
        assert summary["max_grade"] == "ilmelyakin"

    def test_kv4_warnings_tracked(self):
        """KV₄: Summary reports boundary warnings."""
        summary = epistemic_summary()
        assert "kv4_warnings" in summary

    def test_summary_completeness(self):
        """All required fields present."""
        summary = epistemic_summary()
        required = ["total_claims", "structural_claims", "detail_claims",
                     "avg_structural_confidence", "avg_detail_confidence",
                     "t15_verified", "lenses_engaged", "lenses_missing",
                     "max_grade", "station"]
        for field in required:
            assert field in summary, f"Missing field: {field}"
