"""Tests for {{ module_name }} camera interface.

These tests use the fake interface to validate the interface contract
without requiring actual hardware. They cover the full camera lifecycle:
connect, initialize, capture images, configure, shutdown, and disconnect.

Generated by: madsci new module --template module/camera
Template version: {{ template_version }}
"""

import pytest

from {{ module_name }}_fake_interface import {{ module_name | pascal_case }}FakeInterface


class Test{{ module_name | pascal_case }}FakeInterface:
    """Test cases for the {{ module_name }} fake camera interface."""

    @pytest.fixture
    def interface(self) -> {{ module_name | pascal_case }}FakeInterface:
        """Create a test interface instance with low latency."""
        return {{ module_name | pascal_case }}FakeInterface(simulated_latency=0.01)

    def test_initial_state(self, interface: {{ module_name | pascal_case }}FakeInterface) -> None:
        """Test that interface starts disconnected and uninitialized."""
        assert not interface.is_connected
        assert not interface.is_initialized
        assert interface.operation_count == 0
        assert interface.capture_history == []

    def test_connect(self, interface: {{ module_name | pascal_case }}FakeInterface) -> None:
        """Test connection."""
        interface.connect()
        assert interface.is_connected
        assert not interface.is_initialized

    def test_disconnect(self, interface: {{ module_name | pascal_case }}FakeInterface) -> None:
        """Test disconnection."""
        interface.connect()
        interface.disconnect()
        assert not interface.is_connected
        assert not interface.is_initialized

    def test_initialize(self, interface: {{ module_name | pascal_case }}FakeInterface) -> None:
        """Test camera initialization."""
        interface.connect()
        interface.initialize()
        assert interface.is_initialized

    def test_initialize_requires_connection(
        self, interface: {{ module_name | pascal_case }}FakeInterface
    ) -> None:
        """Test that initialization requires connection."""
        with pytest.raises(RuntimeError, match="Not connected"):
            interface.initialize()

    def test_shutdown(self, interface: {{ module_name | pascal_case }}FakeInterface) -> None:
        """Test camera shutdown."""
        interface.connect()
        interface.initialize()
        interface.shutdown()
        assert not interface.is_initialized
        assert interface.is_connected  # Still connected after shutdown

    def test_shutdown_requires_connection(
        self, interface: {{ module_name | pascal_case }}FakeInterface
    ) -> None:
        """Test that shutdown requires connection."""
        with pytest.raises(RuntimeError, match="Not connected"):
            interface.shutdown()

    def test_capture(self, interface: {{ module_name | pascal_case }}FakeInterface) -> None:
        """Test image capture."""
        interface.connect()
        interface.initialize()
        result = interface.capture()

        assert result.width == 1920
        assert result.height == 1080
        assert result.timestamp is not None
        assert result.metadata["exposure_ms"] == 100.0
        assert result.metadata["simulated"] is True
        assert interface.operation_count == 1

    def test_capture_with_settings(
        self, interface: {{ module_name | pascal_case }}FakeInterface
    ) -> None:
        """Test image capture with custom exposure and save path."""
        interface.connect()
        interface.initialize()
        result = interface.capture(exposure_ms=50.0, save_path="/tmp/test.png")

        assert result.image_path == "/tmp/test.png"
        assert result.metadata["exposure_ms"] == 50.0
        assert result.width == 1920
        assert result.height == 1080

    def test_capture_requires_connection(
        self, interface: {{ module_name | pascal_case }}FakeInterface
    ) -> None:
        """Test that capture requires connection."""
        with pytest.raises(RuntimeError, match="Not connected"):
            interface.capture()

    def test_capture_requires_initialization(
        self, interface: {{ module_name | pascal_case }}FakeInterface
    ) -> None:
        """Test that capture requires initialization."""
        interface.connect()
        with pytest.raises(RuntimeError, match="not initialized"):
            interface.capture()

    def test_configure(self, interface: {{ module_name | pascal_case }}FakeInterface) -> None:
        """Test camera configuration."""
        interface.connect()
        result = interface.configure(exposure_ms=200.0, gain=2.5, resolution="1280x720")

        assert result["exposure_ms"] == 200.0
        assert result["gain"] == 2.5
        assert result["resolution"] == "1280x720"

    def test_configure_requires_connection(
        self, interface: {{ module_name | pascal_case }}FakeInterface
    ) -> None:
        """Test that configure requires connection."""
        with pytest.raises(RuntimeError, match="Not connected"):
            interface.configure(exposure_ms=200.0)

    def test_get_image_info(self, interface: {{ module_name | pascal_case }}FakeInterface) -> None:
        """Test getting image info after capture."""
        interface.connect()
        interface.initialize()
        interface.capture()

        info = interface.get_image_info()
        assert info["width"] == 1920
        assert info["height"] == 1080
        assert info["timestamp"] is not None

    def test_get_image_info_no_capture(
        self, interface: {{ module_name | pascal_case }}FakeInterface
    ) -> None:
        """Test getting image info when no capture has occurred."""
        interface.connect()
        info = interface.get_image_info()
        assert info == {}

    def test_get_image_info_requires_connection(
        self, interface: {{ module_name | pascal_case }}FakeInterface
    ) -> None:
        """Test that get_image_info requires connection."""
        with pytest.raises(RuntimeError, match="Not connected"):
            interface.get_image_info()

    def test_get_status(self, interface: {{ module_name | pascal_case }}FakeInterface) -> None:
        """Test status retrieval."""
        interface.connect()
        interface.initialize()
        status = interface.get_status()

        assert status["connected"] is True
        assert status["initialized"] is True
        assert status["resolution"] == "1920x1080"
        assert status["exposure_ms"] == 100.0
        assert status["capture_count"] == 0

    def test_get_status_requires_connection(
        self, interface: {{ module_name | pascal_case }}FakeInterface
    ) -> None:
        """Test that status retrieval requires connection."""
        with pytest.raises(RuntimeError, match="Not connected"):
            interface.get_status()

    def test_get_state(self, interface: {{ module_name | pascal_case }}FakeInterface) -> None:
        """Test internal state retrieval."""
        interface.connect()
        interface.initialize()
        interface.capture()

        state = interface.get_state()

        assert state["connected"] is True
        assert state["initialized"] is True
        assert state["operation_count"] == 1
        assert state["capture_count"] == 1
        assert state["capture_history_length"] == 1
        assert "last_capture_time" in state

    def test_reset_state(self, interface: {{ module_name | pascal_case }}FakeInterface) -> None:
        """Test state reset."""
        interface.connect()
        interface.initialize()
        interface.capture()
        interface.reset_state()

        assert interface.operation_count == 0
        assert interface.capture_history == []
        state = interface.get_state()
        assert state["capture_count"] == 0
        assert "last_capture_time" not in state

    def test_operation_count(self, interface: {{ module_name | pascal_case }}FakeInterface) -> None:
        """Test that operation count increments correctly."""
        interface.connect()
        interface.initialize()

        interface.capture()
        assert interface.operation_count == 1

        interface.capture()
        assert interface.operation_count == 2

        interface.configure(exposure_ms=200.0)
        assert interface.operation_count == 3

    def test_capture_history(self, interface: {{ module_name | pascal_case }}FakeInterface) -> None:
        """Test that capture history is tracked correctly."""
        interface.connect()
        interface.initialize()

        interface.capture(exposure_ms=50.0)
        interface.capture(exposure_ms=100.0, save_path="/tmp/test.png")

        history = interface.capture_history
        assert len(history) == 2
        assert history[0]["exposure_ms"] == 50.0
        assert history[0]["save_path"] is None
        assert history[1]["exposure_ms"] == 100.0
        assert history[1]["save_path"] == "/tmp/test.png"
