# tests/test_chat_cov_features.py
import pytest
from llm_guard.chat_cov_features import ChatCoVFeatureExtractor, CoVFeatureVector

extractor = ChatCoVFeatureExtractor()

COV_WITH_CONTRADICTIONS = """
Step 1 - Claims: The response claims Paris is in Germany.
1. Paris is the capital of Germany.
2. It was founded in 1200.
Step 2 - Evidence: No evidence supports the claim that Paris is in Germany. This is incorrect.
Step 3 - Contradictions: The statement contradicts known facts. It is inaccurate and unsupported.
Step 4 - Confidence: LOW — the response contains false information.
"""

COV_CLEAN = """
Step 1 - Claims: Paris is the capital of France.
1. Paris is located in northern France.
Step 2 - Evidence: Historical and geographical records confirm this.
Step 3 - Contradictions: None found.
Step 4 - Confidence: HIGH — the response is accurate.
"""

COV_MEDIUM = """
Step 1 - Claims: The boiling point of water is 100 degrees.
1. At standard pressure, water boils at 100C.
Step 2 - Evidence: Scientific consensus supports this.
Step 3 - Contradictions: None at standard conditions.
Step 4 - Confidence: MEDIUM — depends on pressure conditions.
"""

def test_contradiction_score_high_when_contradictions_present():
    vec = extractor.extract(COV_WITH_CONTRADICTIONS)
    assert vec.contradiction_score > 0.1

def test_contradiction_score_low_when_clean():
    vec = extractor.extract(COV_CLEAN)
    assert vec.contradiction_score < 0.1

def test_final_confidence_low_maps_to_high_risk():
    vec = extractor.extract(COV_WITH_CONTRADICTIONS)
    assert vec.final_confidence == 0.90

def test_final_confidence_high_maps_to_low_risk():
    vec = extractor.extract(COV_CLEAN)
    assert vec.final_confidence == 0.10

def test_final_confidence_medium():
    vec = extractor.extract(COV_MEDIUM)
    assert vec.final_confidence == 0.50

def test_final_confidence_fallback_on_no_keyword():
    vec = extractor.extract("Step 4 - Confidence: uncertain about everything.")
    assert vec.final_confidence == 0.50

def test_claim_count_norm_positive():
    vec = extractor.extract(COV_WITH_CONTRADICTIONS)
    assert vec.claim_count_norm > 0

def test_to_array_length_is_four():
    vec = extractor.extract(COV_CLEAN)
    assert len(vec.to_array()) == 4

def test_to_array_all_floats():
    vec = extractor.extract(COV_CLEAN)
    assert all(isinstance(v, float) for v in vec.to_array())

def test_to_dict_has_correct_keys():
    vec = extractor.extract(COV_CLEAN)
    assert set(vec.to_dict().keys()) == {
        "contradiction_score", "final_confidence",
        "claim_count_norm", "evidence_gap_ratio"
    }

def test_empty_cov_text_returns_defaults():
    vec = extractor.extract("")
    assert vec.final_confidence == 0.50
    assert vec.contradiction_score == 0.0
    assert len(vec.to_array()) == 4

def test_claim_count_uses_step1_section_only():
    """Claims in Step 2/3/4 must not inflate claim_count_norm."""
    cov_step1_only = """
Step 1 - Claims:
1. Paris is in France.
Step 2 - Evidence:
1. Maps show this.
2. History confirms this.
3. Geography textbooks.
Step 4 - Confidence: HIGH
"""
    vec = extractor.extract(cov_step1_only)
    # Only 1 claim in Step 1, despite 3 numbered items in Step 2
    import math
    expected = math.log1p(1) / 3.0
    assert abs(vec.claim_count_norm - expected) < 1e-9
