from __future__ import annotations

from recoil.pipeline.cli import generate
from recoil.pipeline.core.persistence import load_manifest, save_scene, scene_path
from recoil.pipeline.core.scene_version_store import SceneVersionStore
from recoil.pipeline.core.take import Beat, Scene


def _configure_root(tmp_path, monkeypatch) -> None:
    (tmp_path / ".recoil-data-root").write_text("recoil-data-root\n", encoding="utf-8")
    (tmp_path / "p").mkdir()
    monkeypatch.setenv("RECOIL_PROJECTS_ROOT", str(tmp_path))


def _materialize_v1_v2() -> SceneVersionStore:
    save_scene(
        Scene(scene_id="BATCH_001", beats=[Beat(beat_id="OPENING")]),
        scene_path("p", "ep_001", "BATCH_001"),
    )
    store = SceneVersionStore("p", "ep_001")
    store.write_scene_candidate(
        "BATCH_001",
        Scene(scene_id="BATCH_001", beats=[Beat(beat_id="A"), Beat(beat_id="B")]),
    )
    return store


def test_rederive_conform_dry_run_previews_without_moving_pointer(
    tmp_path, monkeypatch, capsys
):
    _configure_root(tmp_path, monkeypatch)
    _materialize_v1_v2()

    rc = generate._run_rederive_cli([
        "--project", "p",
        "--episode", "1",
        "--batch", "EP001_CONT_001",
        "--conform",
        "--to-version", "2",
        "--dry-run",
    ])

    assert rc == generate.EXIT_OK
    assert load_manifest("p", "ep_001", "BATCH_001")["active_version"] == 1
    out = capsys.readouterr().out
    assert "dry-run" in out
    assert "would move active_version 1 -> 2" in out


def test_rederive_revert_dry_run_previews_without_moving_pointer(
    tmp_path, monkeypatch, capsys
):
    _configure_root(tmp_path, monkeypatch)
    store = _materialize_v1_v2()
    store.conform("BATCH_001", 2)

    rc = generate._run_rederive_cli([
        "--project", "p",
        "--episode", "1",
        "--batch", "EP001_CONT_001",
        "--revert",
        "--to-version", "1",
        "--dry-run",
    ])

    assert rc == generate.EXIT_OK
    assert load_manifest("p", "ep_001", "BATCH_001")["active_version"] == 2
    out = capsys.readouterr().out
    assert "dry-run" in out
    assert "would move active_version 2 -> 1" in out


def test_rederive_pointer_move_without_dry_run_still_mutates(tmp_path, monkeypatch):
    _configure_root(tmp_path, monkeypatch)
    _materialize_v1_v2()

    conform_rc = generate._run_rederive_cli([
        "--project", "p",
        "--episode", "1",
        "--batch", "EP001_CONT_001",
        "--conform",
        "--to-version", "2",
    ])
    assert conform_rc == generate.EXIT_OK
    assert load_manifest("p", "ep_001", "BATCH_001")["active_version"] == 2

    revert_rc = generate._run_rederive_cli([
        "--project", "p",
        "--episode", "1",
        "--batch", "EP001_CONT_001",
        "--revert",
        "--to-version", "1",
    ])
    assert revert_rc == generate.EXIT_OK
    assert load_manifest("p", "ep_001", "BATCH_001")["active_version"] == 1
