"""Tests from Lab 01's prompt makeover: the 8 held-back tickets and real recorded gpt-5.4-nano
replies (temperature 0, one run each). Run: pytest test_triage_practice.py"""
import json

from triage_practice import changed, parse_reply, pick, score

LABELS = {
    17: {"category": "account", "priority": "P3"},          # remove a former employee's access
    18: {"category": "billing", "priority": "P2"},          # charged $650 for removed seats
    19: {"category": "security", "priority": "P1"},         # admin typed a password into a fake login page
    20: {"category": "bug", "priority": "P1"},              # nobody can upload files
    21: {"category": "bug", "priority": "P3"},              # profile picture button, not a big deal
    22: {"category": "billing", "priority": "P3"},          # charged $15 after cancelling the trial
    23: {"category": "account", "priority": "P2"},          # locked out, payroll due today
    24: {"category": "feature_request", "priority": "P3"},  # audit-log export endpoint, "must-have"
}
j = lambda c, p: json.dumps({"category": c, "priority": p}, separators=(",", ":"))
V1 = {t: j(l["category"], l["priority"]) for t, l in LABELS.items()} | {17: j("account", "P2"), 19: j("security", "P3")}
V2 = V1 | {17: j("account", "P3")}

V0_REPLY_19 = "**Category:** Security  \n**Priority:** P1"
V3_REPLY_19 = (
    "<thinking>\n- “Admin clicked a link in a fake login email and typed in their password.” → suspected credential "
    "compromise / phishing attempt → matches category security.\n- Priority: “A suspicious email where nobody clicked a "
    "link or entered details is security, P3.” Here, they did click and entered details, so this is more severe than the "
    "stated P3 case; however, no explicit evidence of breach or product downtime is provided. Still, credential exposure "
    "is serious, but without confirmation of breach, it fits best as P2 (serious security incident affecting an admin’s "
    "credentials).\n</thinking>\n<answer>{\"category\":\"security\",\"priority\":\"P2\"}</answer>"
)


def test_parse_only_what_code_can_rely_on():
    assert parse_reply(V0_REPLY_19) is None                       # right if a person reads it; code can't
    assert parse_reply('{"category":"account","priority":"P2"}') == {"category": "account", "priority": "P2"}
    assert parse_reply(V3_REPLY_19) == {"category": "security", "priority": "P2"}
    assert parse_reply('{"category":"urgent","priority":"P1"}') is None   # not a category
    assert parse_reply('["security","P1"]') is None


def test_version_1_scores_6_of_8():
    assert score(V1, LABELS) == (6, 8)
    assert score({t: V0_REPLY_19 for t in LABELS}, LABELS) == (0, 8)


def test_version_2_fixed_the_ex_employee_and_nothing_else():
    assert score(V2, LABELS) == (7, 8)
    assert changed(V1, V2, LABELS) == {"fixed": [17], "broke": []}


def test_thinking_changed_the_clicked_link_but_did_not_fix_it():
    v3 = V2 | {19: V3_REPLY_19}
    assert changed(V2, v3, LABELS) == {"fixed": [], "broke": []}
    assert score(v3, LABELS) == (7, 8)


def test_pick_the_cheapest_of_the_best():
    versions = [
        {"name": "v1 structured", "holdout": 6, "tokens": 267},
        {"name": "v2 + why", "holdout": 7, "tokens": 435},
        {"name": "v3 + thinking", "holdout": 7, "tokens": 541},
        {"name": "v4 + examples", "holdout": 7, "tokens": 654},
    ]
    assert pick(versions) == "v2 + why"
