"""REC-235: the dead Kling native multi-shot branch is retired.

The native `kling_rest` MultiShotPayload dispatch was UNREACHABLE/dead and
SILENTLY DROPPED shots (VideoModelClient only accepts UnifiedVideoPayload-shaped
dicts). These tests prove:
  1. A kling_rest model now FAILS LOUD (NotImplementedError) instead of silently
     dropping shots.
  2. Every other model still falls through to _execute_sequential_shots.
See divergence multi_shot_native_vs_sequential.
"""
from __future__ import annotations

from unittest.mock import MagicMock, patch

import pytest

from recoil.execution.step_runner import StepRunner


def _make_runner() -> StepRunner:
    # The retired branch raises before touching store/paths, and the
    # sequential fall-through is fully mocked below, so bare stubs suffice.
    return StepRunner.__new__(StepRunner)


_BATCH = [{"shot_id": "S1", "_api_duration": 5}, {"shot_id": "S2", "_api_duration": 5}]
_SEQ = [{"index": 0, "prompt": "a", "duration": 5}, {"index": 1, "prompt": "b", "duration": 5}]


def test_kling_rest_native_multishot_fails_loud_not_silent_drop():
    """A kling_rest model raises NotImplementedError rather than dropping shots."""
    runner = _make_runner()
    with patch(
        "recoil.execution.step_runner.model_profiles.get_api_pattern",
        return_value="kling_rest",
    ):
        with pytest.raises(NotImplementedError) as exc:
            runner.execute_multi_shot(
                batch=_BATCH,
                multi_prompt_sequence=_SEQ,
                model="kling-v3-direct",
            )
    msg = str(exc.value)
    assert "multi_shot_native_vs_sequential" in msg
    assert "silently dropped" in msg


def test_non_kling_model_falls_through_to_sequential():
    """Non-kling_rest models route to the canonical sequential path (no drop)."""
    runner = _make_runner()
    sentinel = ["seq-result"]
    with patch(
        "recoil.execution.step_runner.model_profiles.get_api_pattern",
        return_value="upload_bundle",
    ):
        runner._execute_sequential_shots = MagicMock(return_value=sentinel)
        out = runner.execute_multi_shot(
            batch=_BATCH,
            multi_prompt_sequence=_SEQ,
            model="veo-3.1",
        )
    assert out is sentinel
    runner._execute_sequential_shots.assert_called_once()
    # All shots reach the sequential path — none are silently dropped.
    _, kwargs = runner._execute_sequential_shots.call_args
    assert kwargs["batch"] == _BATCH
    assert kwargs["multi_prompt_sequence"] == _SEQ
