"""Area #3 W2 — shot_director.py mutation 권한 박탈 unit test.

LLM emit visible_entity_ids 가 detect_gaze_pattern_exclusions 결과로
mutate되지 않음을 verify. audit field (excluded_offscreen_entity_ids)
는 그대로 emit. mismatch 시 logger.warning 만.
"""
from unittest.mock import patch


def _make_llm_shots():
    return [
        {
            "shot_index": 1,
            "visible_entity_ids": ["C01", "C02"],
            "variant_resolved": None,
        }
    ]


@patch("app.modules.pipeline.shot_director.call_structured")
@patch("app.modules.pipeline.shot_director.detect_gaze_pattern_exclusions")
def test_no_mutation_when_lexicon_candidates_present(
    mock_exclusions, mock_call,
):
    """LLM emit visible == [C01, C02] + lexicon candidates == {C02: 'name'}
    → post-call visible == [C01, C02] (mutation 없음).
    """
    from app.modules.pipeline.shot_director import _resolve_scene_llm

    mock_call.return_value = {"shots": _make_llm_shots()}
    mock_exclusions.return_value = {"C02": "캐릭터B"}

    result = _resolve_scene_llm(
        scene_index=12,
        scene_ve=["C01", "C02"],
        shots=[{"shot_index": 1, "description": "..."}],
        scene_text="",
        variant_map={},
        entity_name_map={"C01": "캐릭터A", "C02": "캐릭터B"},
        entity_desc_map={"C01": "", "C02": ""},
    )

    assert len(result) == 1
    assert result[0]["visible_entity_ids"] == ["C01", "C02"]  # mutation 없음
    assert result[0]["excluded_offscreen_entity_ids"] == ["C02"]  # audit 유지


@patch("app.modules.pipeline.shot_director.call_structured")
@patch("app.modules.pipeline.shot_director.detect_gaze_pattern_exclusions")
@patch("app.modules.pipeline.shot_director.logger")
def test_logger_warning_on_mismatch(
    mock_logger, mock_exclusions, mock_call,
):
    """LLM emit visible 와 lexicon candidates 교집합이 있으면 logger.warning emit."""
    from app.modules.pipeline.shot_director import _resolve_scene_llm

    mock_call.return_value = {"shots": _make_llm_shots()}
    mock_exclusions.return_value = {"C02": "캐릭터B"}  # C02 in LLM emit

    _resolve_scene_llm(
        scene_index=12,
        scene_ve=["C01", "C02"],
        shots=[{"shot_index": 1, "description": "..."}],
        scene_text="",
        variant_map={},
        entity_name_map={"C01": "캐릭터A", "C02": "캐릭터B"},
        entity_desc_map={"C01": "", "C02": ""},
    )

    assert mock_logger.warning.called
    args, _ = mock_logger.warning.call_args
    assert "Area #3 diagnostic only, no mutation" in args[0], args
