"""Tests for ChatGuard v0.33 — score_chat() default-to-judge fix."""
import sys
import warnings
import pytest
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))

from llm_guard.chat_guard import ChatGuard, ChatResult

Q = "What is the capital of France?"
R = "Paris."


# ── ChatResult has metadata field ─────────────────────────────────────────────

def test_chat_result_has_metadata():
    from dataclasses import fields
    names = [f.name for f in fields(ChatResult)]
    assert "metadata" in names


def test_chat_result_metadata_default_empty():
    r = ChatResult(
        risk_score=0.3, failure_mode="clean", confidence_tier="HIGH",
        behavioral_components={}, processing_time_ms=1.0
    )
    assert r.metadata == {}


def test_to_dict_includes_metadata():
    r = ChatResult(
        risk_score=0.3, failure_mode="clean", confidence_tier="HIGH",
        behavioral_components={}, processing_time_ms=1.0
    )
    r.metadata["foo"] = "bar"
    d = r.to_dict()
    assert "metadata" in d
    assert d["metadata"]["foo"] == "bar"


# ── Unfitted + no api_key → UserWarning ───────────────────────────────────────

def test_unfitted_no_key_emits_warning():
    guard = ChatGuard(mode="native")  # no api_key
    with pytest.warns(UserWarning, match="fit\\(\\)"):
        guard.score_chat(Q, R)


def test_unfitted_no_key_warning_contains_halueval():
    guard = ChatGuard(mode="native")
    with pytest.warns(UserWarning, match="HaluEval"):
        guard.score_chat(Q, R)


# ── Unfitted + api_key → routes to judge ─────────────────────────────────────

def test_unfitted_with_key_sets_routed_flag(monkeypatch):
    """When api_key set and unfitted, routes to judge and sets metadata flag."""
    guard = ChatGuard(api_key="sk-test-key")

    # Monkeypatch score_chat_with_judge to avoid real API call
    from llm_guard.chat_guard import ChatResult as CR
    def fake_judge(query, response, **kwargs):
        return CR(risk_score=0.3, failure_mode="clean", confidence_tier="HIGH",
                  behavioral_components={}, processing_time_ms=1.0)
    monkeypatch.setattr(guard, "score_chat_with_judge", fake_judge)

    result = guard.score_chat(Q, R)
    assert result.metadata.get("routed_to_judge") is True


def test_unfitted_with_key_no_warning(monkeypatch):
    guard = ChatGuard(api_key="sk-test-key")
    from llm_guard.chat_guard import ChatResult as CR
    def fake_judge(query, response, **kwargs):
        return CR(risk_score=0.3, failure_mode="clean", confidence_tier="HIGH",
                  behavioral_components={}, processing_time_ms=1.0)
    monkeypatch.setattr(guard, "score_chat_with_judge", fake_judge)

    with warnings.catch_warnings(record=True) as w:
        warnings.simplefilter("always")
        guard.score_chat(Q, R)
    user_warnings = [x for x in w if issubclass(x.category, UserWarning)]
    assert len(user_warnings) == 0


# ── Fitted path unchanged ─────────────────────────────────────────────────────

def test_fitted_path_no_warning():
    """After fit(), no warning, no routing."""
    guard = ChatGuard(mode="native")
    # Build minimal labeled pairs for fit()
    pairs = [
        {"query": "Q1", "response": "R1", "label": 1},
        {"query": "Q2", "response": "R2", "label": 0},
    ] * 10  # 20 pairs minimum
    guard.fit(pairs)
    with warnings.catch_warnings(record=True) as w:
        warnings.simplefilter("always")
        result = guard.score_chat(Q, R)
    user_warnings = [x for x in w if issubclass(x.category, UserWarning)]
    assert len(user_warnings) == 0
    assert result.metadata.get("routed_to_judge") is not True
