"""Classic pipeline path must also satisfy the {disputes} placeholder added to
CONSTRUCTABILITY_USER_INSTRUCTION (agent path substitutes it in construct_agent.py;
the classic stage builds its own subs dict)."""

from unittest.mock import patch

from backend.pipeline._stage import render
from backend.pipeline.constructability import constructability_review
from backend.prompts import CONSTRUCTABILITY_USER_INSTRUCTION


def _cluster_with_dispute():
    return {
        "key": "c1",
        "assertions": [],
        "disputed_attributes": [{
            "attribute": "stud_pack_size",
            "values": ["(2) 2x6 STUD PACK", "(5) 2x6 STUD PACK"],
            "assertion_ids": ["a1", "a2"],
        }],
    }


def test_classic_constructability_supplies_disputes_sub():
    captured = {}

    def fake_call_stage(system_prompt, user_instruction, subs=None, **kwargs):
        captured["subs"] = subs or {}
        return {"issues": []}

    with patch("backend.pipeline.constructability.call_stage", fake_call_stage):
        constructability_review([], [_cluster_with_dispute()], [])

    assert "disputes" in captured["subs"], "classic path must substitute {disputes}"
    rendered = render(CONSTRUCTABILITY_USER_INSTRUCTION, captured["subs"])
    assert "{disputes}" not in rendered
    assert "(5) 2x6 STUD PACK" in rendered


def test_classic_constructability_disputes_defaults_empty():
    captured = {}

    def fake_call_stage(system_prompt, user_instruction, subs=None, **kwargs):
        captured["subs"] = subs or {}
        return {"issues": []}

    with patch("backend.pipeline.constructability.call_stage", fake_call_stage):
        constructability_review([], [{"key": "c2", "assertions": []}], [])

    rendered = render(CONSTRUCTABILITY_USER_INSTRUCTION, captured["subs"])
    assert "{disputes}" not in rendered
