"""Test that run_shot passes gates to execute_keyframe + FailureMode extraction."""
import pytest
from pathlib import Path
from recoil.pipeline._lib.run_shot import _build_keyframe_gates, _extract_failure_mode
from recoil.pipeline._lib.critics import FailureMode


def test_build_keyframe_gates_with_identity_refs(tmp_path):
    ref1 = tmp_path / "hero.jpg"
    ref1.write_bytes(b"fake")
    ref2 = tmp_path / "front.jpg"
    ref2.write_bytes(b"fake")
    shot = {"identity_refs": [ref1, ref2]}
    gates = _build_keyframe_gates(shot, step_runner=None)
    assert len(gates) == 1
    assert callable(gates[0])


def test_build_keyframe_gates_no_refs():
    shot = {"prompt": "test"}
    gates = _build_keyframe_gates(shot, step_runner=None)
    assert gates == []


def test_build_keyframe_gates_missing_files(tmp_path):
    shot = {"identity_refs": [tmp_path / "nonexistent.jpg"]}
    gates = _build_keyframe_gates(shot, step_runner=None)
    assert gates == []


# --- Phase 4: FailureMode extraction from error strings ---

class FakeStepResult:
    def __init__(self, gate_verdict=None, error="", final_state=""):
        self.gate_verdict = gate_verdict
        self.error = error
        self.final_state = final_state


def test_extract_failure_mode_no_error():
    r = FakeStepResult()
    assert _extract_failure_mode(r) == FailureMode.NONE


def test_extract_failure_mode_content_filter():
    r = FakeStepResult(
        error="content_policy_violation: The images may contain likenesses",
        final_state="video_semantic_failed",
    )
    assert _extract_failure_mode(r) == FailureMode.CONTENT_FILTER_HARD_BLOCK


def test_extract_failure_mode_frame_extraction():
    r = FakeStepResult(
        error="video_frame_critic ERROR: No frames extracted",
        final_state="pending_qc",
    )
    assert _extract_failure_mode(r) == FailureMode.MOTION_FAILURE


def test_extract_failure_mode_identity_from_error():
    r = FakeStepResult(
        error="start_frame_critic hard fail: character identity mismatch",
        final_state="video_semantic_failed",
    )
    assert _extract_failure_mode(r) == FailureMode.IDENTITY_DRIFT


def test_extract_failure_mode_unknown_video_fail():
    r = FakeStepResult(
        error="some unknown error",
        final_state="video_semantic_failed",
    )
    assert _extract_failure_mode(r) == FailureMode.UNKNOWN
