"""Tests on Lab 11's recorded Qwen3-0.6B answers: everyday tasks from 03_regressions.py (before and after
fine-tuning on 2,000 support emails) and product-fact questions from 04_facts.py.
Run: pytest test_regressions_practice.py"""
import pytest

from regressions_practice import check, fact_check, looks_like_ticket, regressions

TICKET = '{"intent": "product_question", "order_id": null, "sku": null, "urgency": "normal"}'


def test_the_checks_are_strict_about_format():
    # "What is 57 + 87? Reply with only the number."
    assert not check("arithmetic", 144, "57 + 87 = 144")       # the untrained model: right sum, but fails
    assert check("arithmetic", 144, "144")                      # QLoRA, and the model trained with replay
    assert not check("arithmetic", 144, '{"number": "57"}')     # the full fine-tune
    # "What is the capital of France? Reply with one word."
    assert check("capital", "Paris", "Paris")
    assert check("capital", "Paris", '{"answer": "Paris"}')    # JSON-wrapped, but still passes
    assert not check("capital", "Paris", "The capital of France is Paris, a city on the Seine.")
    with pytest.raises(ValueError):
        check("haiku", None, "x")


def test_a_check_can_pass_a_leak():
    # The small add-on's bakery sentence passes: the check only asks for one short sentence.
    leak = "BAG-20, a cozy bakery, welcomes a new customer with a delicious cup of coffee and a friendly smile."
    assert check("sentence", None, leak)
    assert not check("sentence", None, '{"sentence": "hello, how can I help you?"}')
    assert not check("sentence", None, "Welcome!")


def test_spot_the_support_ticket():
    assert looks_like_ticket(TICKET)                            # the big add-on, asked for the capital of France
    assert looks_like_ticket('Sure: {"urgency": "high"}')
    assert not looks_like_ticket('{"answer": "Paris"}')         # JSON, but not a ticket
    assert not looks_like_ticket('{"name": "apple", "color": "red"}')
    assert not looks_like_ticket("Paris")
    assert not looks_like_ticket('{"intent": "order_status", "order_id": "A-9387", "sku": "BOOT-W", "urgency":')  # cut off


# Recorded results on the 100 everyday tasks (1 = passed), from data/results/03_regressions.json.
BASE = "0000000000000000000000000000001101111011111110000000100110111111111111111111111111100010111111111111"
RANK8 = "0000000000000000000000000000001111100000100100000000000110111000111111110111111100000000001111111111"
REPLAY = "1011111111101110111000000000001101110101111100000000000111011001111101111111101111100010111111111111"
bits = lambda s: [c == "1" for c in s]


def test_rank_8_lost_more_than_it_gained():
    r = regressions(bits(BASE), bits(RANK8))
    assert (len(r["lost"]), len(r["gained"])) == (18, 1)        # 54 -> 37
    assert r["p"] == pytest.approx(7.63e-5, rel=1e-2)
    assert 80 in r["lost"]                                      # "thank you" in Spanish: gracias -> "thank you"


def test_replay_is_not_a_clean_win():
    r = regressions(bits(BASE), bits(REPLAY))
    assert (len(r["lost"]), len(r["gained"])) == (9, 18)        # 54 -> 63, but 9 tasks it used to pass now fail
    assert r["p"] == pytest.approx(0.122, abs=1e-3)             # within noise
    assert regressions([True, False], [True, False]) == {"lost": [], "gained": [], "p": 1.0}


def test_the_reversal_curse():
    # The add-on trained 10 rounds on the facts, and the untrained model with the facts in its prompt.
    assert fact_check("seen", "Cinder Bivy", 1800, "The Cinder Bivy weighs 1800 g.")["right"]
    assert fact_check("seen", "Cinder Bivy", 1800, "It weighs 1,800 g.")["right"]
    backwards = fact_check("reverse", "Cinder Bivy", 1800, "The Lantern Outfitters weighs 1800 g.")
    assert backwards == {"right": False, "declined": False, "made_up": True}
    assert fact_check("reverse", "Cinder Bivy", 1800,
                      "The Lantern Outfitters product that weighs 1800 g is the Cinder Bivy.")["right"]


def test_made_up_versus_i_dont_know():
    # Asked about a product it was never taught (the Willow Camp Table weighs 2970 g).
    assert fact_check("unknown", "Willow Camp Table", 2970, "The Willow Camp Table weighs 2740 g.") == \
        {"right": False, "declined": False, "made_up": True}
    assert fact_check("unknown", "Willow Camp Table", 71, "I don't know the cost of the Willow Camp Table.") == \
        {"right": False, "declined": True, "made_up": False}
