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

These tests use the fake interface to validate the interface contract
without requiring actual hardware. They cover the full device lifecycle:
connect, initialize, execute commands, shutdown, and disconnect.

Generated by: madsci new module --template module/device
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 device 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.command_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 device 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 device 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_execute_command(self, interface: {{ module_name | pascal_case }}FakeInterface) -> None:
        """Test command execution."""
        interface.connect()
        interface.initialize()
        result = interface.execute_command("test_command", param1="value1")

        assert result["command"] == "test_command"
        assert result["parameters"] == {"param1": "value1"}
        assert result["success"] is True
        assert interface.operation_count == 1

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

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

    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["status_code"] == 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.execute_command("test_command")

        state = interface.get_state()

        assert state["connected"] is True
        assert state["initialized"] is True
        assert state["operation_count"] == 1
        assert state["last_command"] == "test_command"
        assert "last_command_time" in state

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

        assert interface.operation_count == 0
        assert interface.command_history == []
        state = interface.get_state()
        assert "last_command" 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.execute_command("one")
        assert interface.operation_count == 1

        interface.execute_command("two")
        assert interface.operation_count == 2

        interface.execute_command("three")
        assert interface.operation_count == 3

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

        interface.execute_command("cmd_1", x=1)
        interface.execute_command("cmd_2", y=2)

        history = interface.command_history
        assert len(history) == 2
        assert history[0]["command"] == "cmd_1"
        assert history[0]["parameters"] == {"x": 1}
        assert history[1]["command"] == "cmd_2"
        assert history[1]["parameters"] == {"y": 2}
