"""
Tests for the Frozen Core — the most important tests in the system.

If the frozen core doesn't detect correctly, nothing else matters.
"""

import pytest
from biasclear.frozen_core import frozen_core, CORE_VERSION, FrozenCore


class TestCoreVersion:
    def test_version_exists(self):
        assert CORE_VERSION == "1.1.0"

    def test_eval_stamps_version(self):
        result = frozen_core.evaluate("Hello world")
        assert result.core_version == CORE_VERSION


class TestCleanText:
    """Text with no bias should pass clean."""

    def test_neutral_statement(self):
        result = frozen_core.evaluate("The meeting is scheduled for 3pm Tuesday.")
        assert result.aligned is True
        assert result.knowledge_type == "neutral"
        assert len(result.flags) == 0

    def test_factual_with_citation(self):
        result = frozen_core.evaluate(
            "According to the 2023 Census Bureau report (Table B-1), "
            "median household income was $74,580."
        )
        assert result.aligned is True

    def test_short_text(self):
        result = frozen_core.evaluate("OK")
        assert result.aligned is True


class TestConsensusAsEvidence:
    """Tier 1: Consensus language substituting for evidence."""

    def test_everyone_agrees(self):
        result = frozen_core.evaluate(
            "Everyone agrees that this policy is the best approach."
        )
        assert len(result.flags) > 0
        has_flag = any(
            f.pattern_id == "CONSENSUS_AS_EVIDENCE" or "everyone agrees" in f.matched_text
            for f in result.flags
        )
        assert has_flag

    def test_widely_accepted(self):
        result = frozen_core.evaluate(
            "It is widely accepted that the earth revolves around the sun."
        )
        has_flag = any(
            f.pattern_id == "CONSENSUS_AS_EVIDENCE" or "widely accepted" in f.matched_text
            for f in result.flags
        )
        assert has_flag

    def test_all_experts(self):
        result = frozen_core.evaluate(
            "All experts in the field have concluded this is correct."
        )
        has_flag = any(
            f.pattern_id == "CONSENSUS_AS_EVIDENCE" or "all experts" in f.matched_text.lower()
            for f in result.flags
        )
        assert has_flag


class TestClaimWithoutCitation:
    """Tier 1: Authority claims with no source."""

    def test_studies_show(self):
        result = frozen_core.evaluate("Studies show that remote work increases productivity.")
        has_flag = any(
            "CLAIM_WITHOUT_CITATION" in f.pattern_id or "studies show" in f.matched_text
            for f in result.flags
        )
        assert has_flag

    def test_research_indicates(self):
        result = frozen_core.evaluate("Research indicates a strong correlation between sleep and performance.")
        has_flag = any(
            "CLAIM_WITHOUT_CITATION" in f.pattern_id or "research indicates" in f.matched_text
            for f in result.flags
        )
        assert has_flag

    def test_experts_say(self):
        result = frozen_core.evaluate("Experts say the market will recover by Q3.")
        has_flag = any(
            "CLAIM_WITHOUT_CITATION" in f.pattern_id or "experts say" in f.matched_text
            for f in result.flags
        )
        assert has_flag


class TestDissentDismissal:
    """Tier 1: Opposing views dismissed by label."""

    def test_debunked(self):
        result = frozen_core.evaluate(
            "That theory has been thoroughly debunked by the scientific community."
        )
        has_flag = any(f.pattern_id == "DISSENT_DISMISSAL" for f in result.flags)
        assert has_flag

    def test_conspiracy(self):
        result = frozen_core.evaluate(
            "Only conspiracy theorists believe the government was involved."
        )
        has_flag = any(f.pattern_id == "DISSENT_DISMISSAL" for f in result.flags)
        assert has_flag

    def test_no_credible_scientist(self):
        result = frozen_core.evaluate(
            "No credible scientist would support that hypothesis."
        )
        has_flag = any(f.pattern_id == "DISSENT_DISMISSAL" for f in result.flags)
        assert has_flag


class TestFalseBinary:
    """Tier 2: False dilemma / either-or framing."""

    def test_either_or(self):
        result = frozen_core.evaluate(
            "Either we implement this policy now or we face economic collapse."
        )
        has_flag = any(f.pattern_id == "FALSE_BINARY" for f in result.flags)
        assert has_flag

    def test_youre_either(self):
        result = frozen_core.evaluate(
            "You're either with us on this initiative or you're against progress."
        )
        has_flag = any(f.pattern_id == "FALSE_BINARY" for f in result.flags)
        assert has_flag


class TestFearUrgency:
    """Tier 2: Fear-based urgency."""

    def test_catastrophic(self):
        result = frozen_core.evaluate(
            "If we don't act now, the consequences will be catastrophic and irreversible."
        )
        has_flag = any(f.pattern_id == "FEAR_URGENCY" for f in result.flags)
        assert has_flag

    def test_point_of_no_return(self):
        result = frozen_core.evaluate(
            "We are approaching a point of no return on this issue."
        )
        has_flag = any(f.pattern_id == "FEAR_URGENCY" for f in result.flags)
        assert has_flag


class TestShameLever:
    """Tier 2: Shame/social pressure as manipulation."""

    def test_any_reasonable_person(self):
        result = frozen_core.evaluate(
            "Any reasonable person would agree that this is the right approach."
        )
        has_flag = any(f.pattern_id == "SHAME_LEVER" for f in result.flags)
        assert has_flag

    def test_right_side_of_history(self):
        result = frozen_core.evaluate(
            "We need to be on the right side of history on this issue."
        )
        has_flag = any(f.pattern_id == "SHAME_LEVER" for f in result.flags)
        assert has_flag


class TestCredentialAsProof:
    """Tier 3: Credentials substituted for argument."""

    def test_leading_expert(self):
        result = frozen_core.evaluate(
            "As a leading expert in the field, Dr. Smith's opinion should settle the matter."
        )
        has_flag = any(f.pattern_id == "CREDENTIAL_AS_PROOF" for f in result.flags)
        assert has_flag

    def test_years_experience(self):
        result = frozen_core.evaluate(
            "With over 30 years of experience, her judgment is beyond question."
        )
        has_flag = any(f.pattern_id == "CREDENTIAL_AS_PROOF" for f in result.flags)
        assert has_flag


class TestLegalPatterns:
    """Legal domain patterns — opposing counsel rhetorical tools."""

    def test_well_settled(self):
        result = frozen_core.evaluate(
            "It is well-settled law that the defendant's argument fails.",
            domain="legal",
        )
        has_flag = any(f.pattern_id == "LEGAL_SETTLED_DISMISSAL" for f in result.flags)
        assert has_flag

    def test_plainly_meritless(self):
        result = frozen_core.evaluate(
            "Plaintiff's claims are plainly meritless and should be dismissed.",
            domain="legal",
        )
        has_flag = any(f.pattern_id == "LEGAL_MERIT_DISMISSAL" for f in result.flags)
        assert has_flag

    def test_weight_of_authority(self):
        result = frozen_core.evaluate(
            "The overwhelming weight of authority supports the defendant's position.",
            domain="legal",
        )
        has_flag = any(f.pattern_id == "LEGAL_WEIGHT_STACKING" for f in result.flags)
        assert has_flag

    def test_frivolous_vexatious(self):
        result = frozen_core.evaluate(
            "This filing is frivolous and vexatious, warranting sanctions under Rule 11.",
            domain="legal",
        )
        legal_flags = [
            f for f in result.flags
            if f.pattern_id.startswith("LEGAL_")
        ]
        assert len(legal_flags) >= 1

    def test_sanctions_filing_considered(self):
        """Regression: this phrase was missed in v1.0.0."""
        result = frozen_core.evaluate(
            "Filing sanctions should be considered for this vexatious litigation.",
            domain="legal",
        )
        sanctions_flags = [f for f in result.flags if f.pattern_id == "LEGAL_SANCTIONS_THREAT"]
        assert len(sanctions_flags) > 0

    def test_legal_patterns_only_load_for_legal_domain(self):
        """Legal patterns should NOT fire for general domain."""
        result_general = frozen_core.evaluate(
            "It is well-settled law that this is correct.",
            domain="general",
        )
        result_legal = frozen_core.evaluate(
            "It is well-settled law that this is correct.",
            domain="legal",
        )
        legal_flags_general = [f for f in result_general.flags if f.pattern_id.startswith("LEGAL_")]
        legal_flags_legal = [f for f in result_legal.flags if f.pattern_id.startswith("LEGAL_")]
        assert len(legal_flags_legal) > len(legal_flags_general)


class TestTruthScore:
    """Truth score calculation."""

    def test_clean_text_high_score(self):
        from biasclear.scorer import calculate_truth_score
        result = frozen_core.evaluate("The meeting is at 3pm.")
        score = calculate_truth_score(result)
        assert score >= 90

    def test_biased_text_low_score(self):
        from biasclear.scorer import calculate_truth_score
        result = frozen_core.evaluate(
            "Studies show that experts say the consensus is clear. "
            "Everyone agrees this is widely accepted common knowledge. "
            "Only conspiracy theorists would disagree.",
        )
        score = calculate_truth_score(result)
        assert score < 60

    def test_score_bounds(self):
        from biasclear.scorer import calculate_truth_score
        result = frozen_core.evaluate("Hi")
        score = calculate_truth_score(result)
        assert 0 <= score <= 100


class TestKnowledgeClassification:
    """Knowledge type classification."""

    def test_neutral(self):
        result = frozen_core.evaluate("Please send me the document by Friday.")
        assert result.knowledge_type == "neutral"

    def test_sense(self):
        result = frozen_core.evaluate(
            "Experts say that studies show the consensus is clear. "
            "Research indicates authorities confirm the data suggests "
            "it is widely accepted that conventional wisdom holds."
        )
        assert result.knowledge_type == "sense"

    def test_mixed(self):
        result = frozen_core.evaluate(
            "While experts say this is true, the actual data from the "
            "2024 survey (Table 3, p.12) shows a different picture."
        )
        # v1.1.0: citation suppression correctly suppresses "experts say" when
        # a citation (Table 3, p.12) is nearby — text is genuinely neutral
        assert result.knowledge_type in ("mixed", "sense", "neutral")


class TestConfidence:
    """Confidence scoring."""

    def test_structural_match_higher_confidence(self):
        # Structural patterns should yield higher confidence than markers alone
        result_structural = frozen_core.evaluate(
            "That theory has been thoroughly debunked. "
            "No credible scientist supports it. "
            "Any reasonable person would agree."
        )
        result_markers = frozen_core.evaluate("Experts say this is true.")
        # Both should have flags, structural should have higher confidence
        assert len(result_structural.flags) > 0
        assert len(result_markers.flags) > 0

    def test_clean_text_high_confidence(self):
        result = frozen_core.evaluate(
            "According to the Bureau of Labor Statistics report from "
            "January 2025, unemployment decreased by 0.2 percentage points."
        )
        assert result.confidence >= 0.8


class TestImmutability:
    """The core must be immutable."""

    def test_singleton_identity(self):
        from biasclear.frozen_core import frozen_core as core2
        assert frozen_core is core2

    def test_principles_not_modifiable(self):
        """Principles dict shouldn't be mutated at runtime."""
        original_count = len(frozen_core._base_patterns)
        # Attempt to evaluate — should not change pattern count
        frozen_core.evaluate("test text")
        assert len(frozen_core._base_patterns) == original_count
