"""
Tests for perfect_cuboid.quality — Quality assessment & kavaid compliance.

Tests:
  AX51: Quality framework completeness
  AX52: Multiplicative gate (zero in any dim = collapse)
  AX53/T17: Ahfâ inaccessibility → 6/7 max coverage
  AX56: Grade ceiling
  AX57: Transparency
  KV₁–KV₈: All 8 kavaid constraints
  §7.2: Four structural incompleteness results
"""

import pytest

from perfect_cuboid.quality import (
    KavaidCheck,
    QualityReport,
    run_kavaid_checks,
    assess_structural_incompleteness,
    run_full_quality_assessment,
)


class TestKavaidRegister:
    """All 8 kavaid must be satisfied."""

    def test_all_eight_kavaid_present(self):
        checks = run_kavaid_checks()
        ids = {c.id for c in checks}
        assert ids == {f"KV{i}" for i in range(1, 9)}

    def test_all_kavaid_pass(self):
        checks = run_kavaid_checks()
        for c in checks:
            assert c.satisfied, f"{c.id} ({c.name}) failed: {c.evidence}"

    def test_each_has_evidence(self):
        checks = run_kavaid_checks()
        for c in checks:
            assert len(c.evidence) > 20, f"{c.id} lacks evidence"

    def test_kv4_composite_bounded(self):
        """KV₄: 0 < Composite < 1."""
        checks = run_kavaid_checks()
        kv4 = [c for c in checks if c.id == "KV4"][0]
        assert kv4.satisfied
        assert kv4.warning == ""  # no theological warning

    def test_kv7_independence(self):
        """KV₇: No shared state between lenses."""
        checks = run_kavaid_checks()
        kv7 = [c for c in checks if c.id == "KV7"][0]
        assert kv7.satisfied
        assert "independent" in kv7.evidence.lower() or \
               "no shared state" in kv7.evidence.lower()


class TestStructuralIncompleteness:
    """§7.2 — Four structural bounds must be honored."""

    def test_t17_coverage_bound(self):
        """T17: Coverage ≤ 6/7."""
        bounds = assess_structural_incompleteness()
        assert bounds["T17_coverage"]["result"] == "6/7"
        assert bounds["T17_coverage"]["bound_respected"]

    def test_ax56_grade_ceiling(self):
        """AX56: Max grade = İlmelyakîn."""
        bounds = assess_structural_incompleteness()
        result = bounds["AX56_grade_ceiling"]["result"]
        assert "lmelyak" in result.lower()  # Turkish İ→i̇ unicode-safe
        assert bounds["AX56_grade_ceiling"]["bound_respected"]

    def test_ax58_gap_acknowledged(self):
        """AX58: Şuhud–İstidlal gap acknowledged."""
        bounds = assess_structural_incompleteness()
        assert bounds["AX58_suhud_istidlal_gap"]["bound_respected"]

    def test_kv4_composite_bound(self):
        """KV₄: 0 < C < 1."""
        bounds = assess_structural_incompleteness()
        result = bounds["KV4_composite_bound"]["result"]
        assert "0 <" in result and "< 1" in result
        assert bounds["KV4_composite_bound"]["bound_respected"]

    def test_all_bounds_respected(self):
        bounds = assess_structural_incompleteness()
        for key, val in bounds.items():
            assert val["bound_respected"], f"Bound {key} NOT respected"


class TestFullQualityReport:
    """AX51 — Complete quality assessment Q-1 through Q-4."""

    def test_latife_vector_is_6_of_7(self):
        """T17: 6/7 faculties, Ahfâ = 0."""
        report = run_full_quality_assessment()
        assert len(report.latife_vector) == 7
        assert sum(report.latife_vector) == 6
        assert report.latife_vector[6] == 0  # Ahfâ

    def test_coverage_gate_passes(self):
        """AX52: Multiplicative gate — all accessible faculties = 1."""
        report = run_full_quality_assessment()
        assert report.coverage_gate is True

    def test_grade_valid(self):
        """AX56: Grade ≤ İlmelyakîn."""
        report = run_full_quality_assessment()
        assert report.grade_valid
        assert report.max_grade == "ilmelyakin"

    def test_all_kavaid_pass(self):
        report = run_full_quality_assessment()
        assert report.all_kavaid_pass

    def test_composite_in_bounds(self):
        """KV₄: 0 < composite < 1."""
        report = run_full_quality_assessment()
        assert 0 < report.composite_score < 1
        assert report.composite_valid

    def test_completeness_is_6_7(self):
        report = run_full_quality_assessment()
        assert report.completeness == "6/7"

    def test_transparency_statement_nonempty(self):
        """AX57: Transparency statement must be substantive."""
        report = run_full_quality_assessment()
        assert len(report.transparency_statement) > 100

    def test_structural_bounds_present(self):
        report = run_full_quality_assessment()
        assert len(report.structural_bounds) == 4

    def test_multiplicative_gate_not_weighted_average(self):
        """AX52: Gate is multiplicative, NOT weighted average.
        If ANY latife is 0 (besides Ahfâ), gate collapses."""
        report = run_full_quality_assessment()
        # Simulate: if we set Akil to 0, gate should fail
        modified = [0, 1, 1, 1, 1, 1, 0]
        gate = all(modified[i] == 1 for i in range(6))
        assert gate is False  # Collapsed — not compensated by high others
