"""
Phase 2 — Kavaid Falsifiability Tests (WATERFALL_PLAN §6.4)

Tests 2.01–2.15: Verify KV₂, KV₃, KV₅ are computationally falsifiable.
These kavaid were previously hardcoded True in bileshke/quality.py.
Phase 2 replaces them with heuristic check functions that CAN fail.

TDD: This file is written FIRST (red phase). Implementation follows.
"""

from __future__ import annotations

import pytest

# ---------------------------------------------------------------------------
# 2.01 – 2.04: KV₂ — Privation Ontology of Evil (AX60)
# ---------------------------------------------------------------------------


class TestKV2PrivationOntology:
    """KV₂: Evil is absence (adem), never a positive entity (vücud)."""

    def test_kv2_passes_neutral_text(self):
        """2.01: Non-defect text → KV₂ passes (True)."""
        from bileshke.quality import _check_kv2

        text = "The sun rose over the calm sea. Birds flew across the sky."
        result = _check_kv2(text, [])
        assert result is True

    def test_kv2_passes_privation_framing(self):
        """2.02: Proper privation language → KV₂ passes.
        
        'absence of X', 'lack of Y' — treating deficiency as absence.
        """
        from bileshke.quality import _check_kv2

        text = "The failure was due to absence of proper validation. The lack of input checking led to the gap."
        result = _check_kv2(text, ["diagnosis"])
        assert result is True

    def test_kv2_fails_positive_evil(self):
        """2.03: Evil treated as positive entity → KV₂ fails (False).
        
        FALSIFICATION: 'evil creates disorder' attributes causal agency.
        """
        from bileshke.quality import _check_kv2

        text = "Evil creates disorder in the system. The malicious force generates corruption."
        result = _check_kv2(text, [])
        assert result is False

    def test_kv2_fails_force_attribution(self):
        """2.04: Deficiency attributed as a force → KV₂ fails.
        
        FALSIFICATION: 'darkness is a force' — treats absence as entity.
        """
        from bileshke.quality import _check_kv2

        text = "Darkness is a force that opposes the light. Chaos is an agent of destruction."
        result = _check_kv2(text, [])
        assert result is False

    def test_kv2_passes_empty_text(self):
        """2.01b: Empty text → KV₂ trivially passes (no content to violate)."""
        from bileshke.quality import _check_kv2

        assert _check_kv2("", []) is True

    def test_kv2_passes_diagnosis_with_privation(self):
        """2.02b: Diagnosis context with proper privation framing passes."""
        from bileshke.quality import _check_kv2

        text = "The bug is a gap in the validation layer — the absence of a null check."
        result = _check_kv2(text, ["P3", "diagnosis"])
        assert result is True


# ---------------------------------------------------------------------------
# 2.05 – 2.07: KV₃ — Observer Non-Interference (AX43)
# ---------------------------------------------------------------------------


class TestKV3ObserverNonInterference:
    """KV₃: Methodology detects order, never creates it."""

    def test_kv3_passes_normal(self):
        """2.05: Normal text with proportional evidence → KV₃ passes."""
        from bileshke.quality import _check_kv3

        # 50 words with several vocab hits → evidence density is fine
        text = (
            "The ontological structure of this system reveals a clear pattern. "
            "The functor maps representation to reality through holographic seeds. "
            "Each mereological part reflects the whole via Vahidiyet containment. "
            "The Bayesian analysis confirms the structural pattern convergence with "
            "high reliability across multiple independent channels."
        )
        lens_scores = {"Ontoloji": 0.3, "Mereoloji": 0.2, "FOL": 0.1}
        vocab_hits = ["ontological", "functor", "holographic", "mereological",
                      "Vahidiyet", "Bayesian", "structural", "convergence"]
        result = _check_kv3(text, lens_scores, vocab_hits)
        assert result is True

    def test_kv3_fails_phantom_structure(self):
        """2.06: 10-word input with suspiciously high score → KV₃ fails.
        
        FALSIFICATION: High scores with minimal evidence = over-interpretation.
        """
        from bileshke.quality import _check_kv3

        text = "Hello world this is a very short ten word text."
        lens_scores = {"Ontoloji": 0.6, "FOL": 0.5}
        vocab_hits = []  # No vocabulary matches at all
        result = _check_kv3(text, lens_scores, vocab_hits)
        assert result is False

    def test_kv3_passes_empty_text(self):
        """2.07: Empty text → passes trivially (no content to over-interpret)."""
        from bileshke.quality import _check_kv3

        result = _check_kv3("", {"Ontoloji": 0.3}, ["something"])
        assert result is True

    def test_kv3_passes_no_lens_scores(self):
        """2.05b: No lens scores → passes (nothing to compare against)."""
        from bileshke.quality import _check_kv3

        result = _check_kv3("some text here", {}, [])
        assert result is True

    def test_kv3_passes_low_scores(self):
        """2.05c: Low scores regardless of evidence → passes (no over-interpretation)."""
        from bileshke.quality import _check_kv3

        text = "Short input."
        lens_scores = {"Ontoloji": 0.1, "FOL": 0.05}
        vocab_hits = []
        result = _check_kv3(text, lens_scores, vocab_hits)
        assert result is True


# ---------------------------------------------------------------------------
# 2.08 – 2.10: KV₅ — Functor Verification (KV₅)
# ---------------------------------------------------------------------------


class TestKV5FunctorVerification:
    """KV₅: Rep→Hakikat functor is faithful + natural."""

    def test_kv5_passes_no_category_lens(self):
        """2.08: Category score = 0 → no category data → passes by default."""
        from bileshke.quality import _check_kv5

        result = _check_kv5(
            lens_scores={"Ontoloji": 0.3},
            kategori_score=0.0,
            kategori_checks=None,
        )
        assert result is True

    def test_kv5_passes_valid_functor(self):
        """2.09: Category checks all True → functor locally verified → passes."""
        from bileshke.quality import _check_kv5

        result = _check_kv5(
            lens_scores={"KategoriTeorisi": 0.4},
            kategori_score=0.4,
            kategori_checks={"vahidiyet": True, "ehadiyet": True},
        )
        assert result is True

    def test_kv5_fails_vahidiyet_violation(self):
        """2.10: Vahidiyet check failed → KV₅ fails.
        
        FALSIFICATION: Category lens ran but structural connectivity broken.
        """
        from bileshke.quality import _check_kv5

        result = _check_kv5(
            lens_scores={"KategoriTeorisi": 0.4},
            kategori_score=0.4,
            kategori_checks={"vahidiyet": False, "ehadiyet": True},
        )
        assert result is False

    def test_kv5_fails_ehadiyet_violation(self):
        """2.10b: Ehadiyet check failed → KV₅ fails."""
        from bileshke.quality import _check_kv5

        result = _check_kv5(
            lens_scores={"KategoriTeorisi": 0.3},
            kategori_score=0.3,
            kategori_checks={"vahidiyet": True, "ehadiyet": False},
        )
        assert result is False

    def test_kv5_passes_no_checks_dict(self):
        """2.08b: Category ran but no checks dict → defaults to True."""
        from bileshke.quality import _check_kv5

        result = _check_kv5(
            lens_scores={"KategoriTeorisi": 0.2},
            kategori_score=0.2,
            kategori_checks=None,
        )
        assert result is True


# ---------------------------------------------------------------------------
# 2.11 – 2.12: Integration — Q-3 function
# ---------------------------------------------------------------------------


class TestQ3Integration:
    """Tests that compute_q3_kavaid uses the new check functions."""

    def test_q3_uses_new_checks(self):
        """2.11: Full Q-3 with toxic content → KV₂ fails (not hardcoded True)."""
        from bileshke.quality import compute_q3_kavaid

        result = compute_q3_kavaid(
            composite_score=0.5,
            lens_scores={"Ontoloji": 0.3, "Topoloji + Holografik": 0.2},
            text="Evil creates disorder and chaos is an agent.",
            patterns_applied=[],
            vocab_hits=["disorder", "chaos"],
            kategori_checks=None,
        )
        checks = result["checks"]
        # KV₂ should FAIL for this input — proves it's not hardcoded True
        assert checks["KV2"] is False

    def test_q3_backward_compat(self):
        """2.12: Old caller (no new params) → works, returns valid result."""
        from bileshke.quality import compute_q3_kavaid

        result = compute_q3_kavaid(
            composite_score=0.5,
            lens_scores={"Ontoloji": 0.3, "Topoloji + Holografik": 0.2},
        )
        assert "checks" in result
        assert "passed" in result
        # Old callers get structural defaults (True) — backward compat
        checks = result["checks"]
        assert "KV2" in checks
        assert "KV3" in checks
        assert "KV5" in checks

    def test_q3_phantom_structure_fails_kv3(self):
        """2.11b: Phantom structure input → KV₃ fails via Q-3."""
        from bileshke.quality import compute_q3_kavaid

        result = compute_q3_kavaid(
            composite_score=0.3,
            lens_scores={"Ontoloji": 0.6, "FOL": 0.5},
            text="Hello world short text.",
            vocab_hits=[],
            patterns_applied=[],
            kategori_checks=None,
        )
        checks = result["checks"]
        assert checks["KV3"] is False

    def test_q3_vahidiyet_violation_fails_kv5(self):
        """2.11c: Vahidiyet violation → KV₅ fails via Q-3."""
        from bileshke.quality import compute_q3_kavaid

        result = compute_q3_kavaid(
            composite_score=0.3,
            lens_scores={"KategoriTeorisi": 0.4},
            text="Category theory analysis.",
            vocab_hits=["category"],
            patterns_applied=[],
            kategori_checks={"vahidiyet": False, "ehadiyet": True},
        )
        checks = result["checks"]
        assert checks["KV5"] is False


# ---------------------------------------------------------------------------
# 2.13: Dusun flow integration
# ---------------------------------------------------------------------------


class TestDusunKavaidFlow:
    """Verify dusun() passes new params to Q-3."""

    def test_dusun_passes_kavaid_to_q3(self):
        """2.13: dusun() flow → new params reach Q-3.
        
        When dusun() is called with evil-framing text, KV₂ should detect it.
        We verify by checking the kavaid result in dusun output.
        """
        from fw_server.dusun import dusun

        result = dusun("Evil creates disorder. Darkness is a force that destroys everything.")
        kavaid = result.get("kavaid", {})
        # The kavaid dict should exist and contain checks sub-dict
        assert isinstance(kavaid, dict)
        checks = kavaid.get("checks", {})
        # KV₂ should be falsified for this content
        assert checks.get("KV2") is False


# ---------------------------------------------------------------------------
# 2.14: Falsifiability meta-test
# ---------------------------------------------------------------------------


class TestKavaidFalsifiability:
    """Meta-test: each new KV has at least one failing case."""

    def test_kavaid_falsifiable_unit(self):
        """2.14: Confirm each of KV₂, KV₃, KV₅ can be falsified."""
        from bileshke.quality import _check_kv2, _check_kv3, _check_kv5

        # KV₂ falsification
        assert _check_kv2("Evil creates disorder", []) is False

        # KV₃ falsification
        assert _check_kv3(
            "Short txt", {"Ontoloji": 0.6}, []
        ) is False

        # KV₅ falsification
        assert _check_kv5(
            lens_scores={"KategoriTeorisi": 0.4},
            kategori_score=0.4,
            kategori_checks={"vahidiyet": False, "ehadiyet": True},
        ) is False


# ---------------------------------------------------------------------------
# 2.15: Regression baseline
# ---------------------------------------------------------------------------


class TestRegressionBaseline:
    """Ensure no existing functionality is broken."""

    def test_regression_baseline(self):
        """2.15: compute_q3_kavaid with no args → valid, all-True defaults."""
        from bileshke.quality import compute_q3_kavaid

        result = compute_q3_kavaid()
        assert result["component"] == "Q-3"
        assert "checks" in result
        assert result["passed"] is True

    def test_old_style_kavaid_override(self):
        """2.15b: Caller-provided kavaid_checks still override."""
        from bileshke.quality import compute_q3_kavaid

        result = compute_q3_kavaid(
            kavaid_checks={"KV2": False, "KV3": False},
            composite_score=0.5,
        )
        checks = result["checks"]
        assert checks["KV2"] is False
        assert checks["KV3"] is False
        assert result["passed"] is False

    def test_build_quality_report_still_works(self):
        """2.15c: build_quality_report (old caller) still works."""
        from bileshke.quality import build_quality_report
        from bileshke.types import LatifeVektor, OrtamVektor

        report = build_quality_report(
            results=[],
            composite_score=0.5,
            latife=LatifeVektor(bits=(1, 1, 1, 1, 1, 1, 0)),
            ortam=OrtamVektor(bits=(1, 1, 1)),
        )
        assert "Q3_kavaid" in report
        assert report["Q3_kavaid"]["passed"] is True


# ---------------------------------------------------------------------------
# 2.16 – 2.17: Empirical False-Positive Sweep (Gate §6.6 criterion 4)
# "KV₂/₃/₅ pass for 10 diverse neutral texts"
# ---------------------------------------------------------------------------

# 10 diverse neutral texts spanning different domains
_DIVERSE_NEUTRAL_TEXTS = [
    # 1. Software engineering
    "The microservice architecture uses an API gateway for routing. "
    "Each service has its own database and communicates via gRPC.",
    # 2. Mathematics
    "The Riemann hypothesis states that all non-trivial zeros of the "
    "zeta function have real part equal to one-half.",
    # 3. Biology
    "Photosynthesis converts carbon dioxide and water into glucose and "
    "oxygen using sunlight energy captured by chlorophyll molecules.",
    # 4. Philosophy
    "Kant argued that synthetic a priori knowledge is possible because "
    "the mind actively structures experience through categories.",
    # 5. Literature
    "The novel explores themes of identity through a first-person "
    "narrator who gradually discovers the unreliability of memory.",
    # 6. Music
    "A fugue in B-flat minor opens with a subject in the bass voice, "
    "followed by the answer in the soprano at the dominant.",
    # 7. Economics
    "Supply and demand equilibrium determines the market price. When "
    "supply exceeds demand, prices tend to fall over time.",
    # 8. Physics
    "General relativity describes gravity as curvature of spacetime "
    "caused by mass and energy, replacing Newtonian mechanics.",
    # 9. Cooking
    "Sear the steak on high heat for two minutes per side. Let it "
    "rest for five minutes before slicing against the grain.",
    # 10. History
    "The printing press, invented by Gutenberg around 1440, enabled "
    "mass production of books and accelerated the spread of knowledge.",
]


class TestEmpiricalFalsePositiveSweep:
    """Gate §6.6: No false positives on 10 diverse neutral texts."""

    @pytest.mark.parametrize(
        "text", _DIVERSE_NEUTRAL_TEXTS, ids=[f"text_{i}" for i in range(10)]
    )
    def test_kv2_no_false_positive(self, text):
        """2.16a: KV₂ passes for each diverse neutral text."""
        from bileshke.quality import _check_kv2

        assert _check_kv2(text, []) is True

    @pytest.mark.parametrize(
        "text", _DIVERSE_NEUTRAL_TEXTS, ids=[f"text_{i}" for i in range(10)]
    )
    def test_kv3_no_false_positive(self, text):
        """2.16b: KV₃ passes for each diverse neutral text.

        Scores are proportional to text length (simulating realistic lens output).
        """
        from bileshke.quality import _check_kv3

        # Simulate realistic lens scores proportional to text substance
        vocab = text.split()[:5]  # at least some vocabulary evidence
        scores = {"Ontoloji": 0.2, "Mereoloji": 0.15, "FOL": 0.1}
        assert _check_kv3(text, scores, vocab) is True

    @pytest.mark.parametrize(
        "text", _DIVERSE_NEUTRAL_TEXTS, ids=[f"text_{i}" for i in range(10)]
    )
    def test_kv5_no_false_positive(self, text):
        """2.16c: KV₅ passes for each diverse neutral text (no category data)."""
        from bileshke.quality import _check_kv5

        # No category lens data → structural True (correct default)
        assert _check_kv5({}, 0.0, None) is True

    def test_dusun_no_kavaid_false_positive(self):
        """2.17: dusun() end-to-end on 5 diverse neutral texts → all KV pass.

        This is the empirical end-to-end gate test: real dusun() calls with
        innocuous inputs must not trigger false kavaid failures.
        """
        from fw_server.dusun import dusun

        for i, text in enumerate(_DIVERSE_NEUTRAL_TEXTS[:5]):
            result = dusun(text)
            kavaid = result.get("kavaid", {})
            checks = kavaid.get("checks", {})
            for kv_id in ("KV2", "KV3", "KV5"):
                assert checks.get(kv_id) is not False, (
                    f"False positive: {kv_id} failed on text_{i}: "
                    f"{text[:60]}..."
                )
