"""Tests for {{ interface_name }} socket interface.

Generated by: madsci new comm --template comm/socket
Template version: {{ template_version }}
"""

import pytest

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


class Test{{ interface_name | pascal_case }}FakeInterface:
    """Test cases for the fake socket interface."""

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

    @pytest.fixture
    def udp_interface(self) -> {{ interface_name | pascal_case }}FakeInterface:
        """Create a UDP test interface instance with zero latency."""
        return {{ interface_name | pascal_case }}FakeInterface(protocol="udp", simulated_latency=0.0)

    def test_initial_state(self, interface: {{ interface_name | pascal_case }}FakeInterface) -> None:
        """Test that the interface starts disconnected."""
        assert not interface.is_connected
        assert interface.operation_count == 0
        assert interface.send_history == []

    def test_connect_disconnect(self, interface: {{ interface_name | pascal_case }}FakeInterface) -> None:
        """Test connecting and disconnecting."""
        interface.connect()
        assert interface.is_connected
        interface.disconnect()
        assert not interface.is_connected

    def test_send(self, interface: {{ interface_name | pascal_case }}FakeInterface) -> None:
        """Test sending data."""
        interface.connect()
        n = interface.send(b"hello")
        assert n == 5
        assert interface.send_history == [b"hello"]
        assert interface.operation_count == 1

    def test_send_requires_connection(self, interface: {{ interface_name | pascal_case }}FakeInterface) -> None:
        """Test that sending without connection raises an error."""
        with pytest.raises(RuntimeError, match="not connected"):
            interface.send(b"test")

    def test_receive(self, interface: {{ interface_name | pascal_case }}FakeInterface) -> None:
        """Test receiving data."""
        interface.set_response(b"world")
        interface.connect()
        data = interface.receive()
        assert data == b"world"
        assert interface.operation_count == 1

    def test_receive_requires_connection(self, interface: {{ interface_name | pascal_case }}FakeInterface) -> None:
        """Test that receiving without connection raises an error."""
        with pytest.raises(RuntimeError, match="not connected"):
            interface.receive()

    def test_receive_consumes_buffer(self, interface: {{ interface_name | pascal_case }}FakeInterface) -> None:
        """Test that receive consumes data from the buffer."""
        interface.set_response(b"abcdef")
        interface.connect()
        first = interface.receive(size=3)
        second = interface.receive(size=3)
        assert first == b"abc"
        assert second == b"def"

    def test_query(self, interface: {{ interface_name | pascal_case }}FakeInterface) -> None:
        """Test the query convenience method."""
        interface.set_response(b"OK")
        interface.connect()
        response = interface.query("STATUS")
        assert response == "OK"
        assert b"STATUS\n" in interface.send_history

    def test_query_requires_connection(self, interface: {{ interface_name | pascal_case }}FakeInterface) -> None:
        """Test that query without connection raises an error."""
        with pytest.raises(RuntimeError, match="not connected"):
            interface.query("STATUS")

    def test_invalid_protocol(self) -> None:
        """Test that an invalid protocol raises ValueError."""
        with pytest.raises(ValueError, match="Unsupported protocol"):
            {{ interface_name | pascal_case }}FakeInterface(protocol="sctp")

    def test_udp_interface(self, udp_interface: {{ interface_name | pascal_case }}FakeInterface) -> None:
        """Test that UDP interface works the same as TCP for basic operations."""
        udp_interface.connect()
        assert udp_interface.is_connected
        udp_interface.set_response(b"pong")
        n = udp_interface.send(b"ping")
        assert n == 4
        data = udp_interface.receive()
        assert data == b"pong"

    def test_reset(self, interface: {{ interface_name | pascal_case }}FakeInterface) -> None:
        """Test that reset clears all internal state."""
        interface.connect()
        interface.send(b"data")
        interface.reset()
        assert interface.operation_count == 0
        assert interface.send_history == []

    def test_multiple_sends(self, interface: {{ interface_name | pascal_case }}FakeInterface) -> None:
        """Test that multiple sends are tracked in order."""
        interface.connect()
        interface.send(b"first")
        interface.send(b"second")
        assert interface.send_history == [b"first", b"second"]
        assert interface.operation_count == 2
