from bubblecam import state_lib
from conftest import load_bin_module

epaper_display = load_bin_module("epaper_display")


def cfg():
    return {
        "camera": {"mode": "sbs_mjpeg", "resolution": "3200x1200", "device_primary": "/dev/video0"},
        "epaper": {
            "idle_toggle_seconds": 5,
            "recording_refresh_seconds": 10,
            "full_refresh_every": 30,
            "preview_resolution": "640x240",
        },
        "paths": {"video_dir": "/nonexistent-on-dev-machine"},
    }


def test_build_data_image_has_correct_dimensions(sim_env):
    image = epaper_display.build_data_image(cfg())
    assert image.size == (250, 122)
    assert image.mode == "1"


def test_build_data_image_reflects_not_recording_when_camera_absent(sim_env):
    # Rendering itself doesn't assert on text content (no OCR), but this
    # exercises the "no camera state yet" branch without raising.
    image = epaper_display.build_data_image(cfg())
    assert image is not None


def test_build_data_image_does_not_raise_with_full_state(sim_env):
    state_lib.write_state("camera_primary", "running")
    state_lib.write_state("sensors", "running", temperature_c=21.4, humidity_pct=63.2, pressure_hpa=1012.7)
    image = epaper_display.build_data_image(cfg())
    assert image.size == (250, 122)


def test_build_camera_image_sim_falls_back_to_placeholder(sim_env):
    # In sim mode there is no camera; the preview screen must still render
    # a valid panel-sized 1-bit image (with the "unavailable" message).
    image = epaper_display.build_camera_image(cfg())
    assert image.size == (250, 122)
    assert image.mode == "1"


def test_recording_active_tracks_camera_state(sim_env):
    assert epaper_display.recording_active(cfg()) is False
    state_lib.write_state("camera_primary", "running")
    assert epaper_display.recording_active(cfg()) is True


def test_preview_grab_never_uses_recording_resolution(monkeypatch):
    """Regression guard: previewing at the recording resolution once
    OOM-killed the Pi off the network (512MB, no swap). The preview must
    always capture at epaper.preview_resolution."""
    captured = {}

    def fake_run(cmd, **kwargs):
        captured["cmd"] = cmd
        raise RuntimeError("no camera on the dev machine")

    monkeypatch.setattr(epaper_display.subprocess, "run", fake_run)
    monkeypatch.delenv("BUBBLECAM_SIM", raising=False)

    assert epaper_display.grab_camera_frame(cfg()) is None
    cmd = captured["cmd"]
    assert cmd[cmd.index("-video_size") + 1] == "640x240"
    assert "3200x1200" not in cmd


def test_camera_service_names_dual_node():
    assert epaper_display.camera_service_names({"camera": {"mode": "dual_node_mjpeg"}}) == [
        "camera_left",
        "camera_right",
    ]
