"""The pinned parse rules — the ones two runtimes disagree on."""

from __future__ import annotations

from alert_triage.protocol import extract_candidate, parse_reply

FENCE = "```"


def test_fence_wins_over_an_earlier_bare_brace() -> None:
    text = 'first {not it} then ' + FENCE + 'json\n{"action":"lookup","what":"documents"}\n' + FENCE
    assert extract_candidate(text) == '{"action":"lookup","what":"documents"}\n'
    obj, reason = parse_reply(text)
    assert obj == {"action": "lookup", "what": "documents"} and reason is None


def test_first_balanced_span_is_string_aware() -> None:
    text = 'ok {"note":"a } inside \\" quotes","action":"close"} trailing {"x":1}'
    obj, _ = parse_reply(text)
    assert obj == {"note": 'a } inside " quotes', "action": "close"}


def test_invalid_first_span_is_rejected_without_further_scanning() -> None:
    obj, reason = parse_reply('{"a":1,} {"action":"lookup","what":"documents"}')
    assert obj is None and reason


def test_non_object_json_is_rejected() -> None:
    assert parse_reply("[1,2]")[0] is None
    assert parse_reply(FENCE + "json\n[{\"action\":\"lookup\"}]\n" + FENCE)[0] is None
    assert parse_reply("42")[0] is None


def test_nan_and_infinity_are_rejected_like_json_parse_does() -> None:
    assert parse_reply('{"x":NaN}')[0] is None
    assert parse_reply('{"x":Infinity}')[0] is None


def test_unbalanced_or_absent_braces() -> None:
    assert parse_reply('{"action":"lookup"')[0] is None
    assert parse_reply("no braces at all")[0] is None
    assert parse_reply("")[0] is None
    assert parse_reply(None)[0] is None


def test_nested_object_is_the_outer_one() -> None:
    obj, _ = parse_reply('{"outer":{"action":"lookup"}}')
    assert obj == {"outer": {"action": "lookup"}}
