"""Tests for AR488InstrSession."""

from pyvisa.constants import ResourceAttribute, StatusCode

from pyvisa_ar488.sessions import AR488InstrSession


class TestSessionAttributes:
    """Test VISA attribute get/set on instrument sessions."""

    def test_default_timeout(self, mock_transport):
        mock_transport.connect()
        sess = AR488InstrSession(
            transport=mock_transport,
            resource_name="GPIB0::5::INSTR",
            primary_address=5,
        )
        value, status = sess.get_attribute(ResourceAttribute.timeout_value)
        assert status == StatusCode.success
        assert value == 10000  # default 10s

    def test_set_timeout(self, mock_transport):
        mock_transport.connect()
        sess = AR488InstrSession(
            transport=mock_transport,
            resource_name="GPIB0::5::INSTR",
            primary_address=5,
        )
        status = sess.set_attribute(ResourceAttribute.timeout_value, 5000)
        assert status == StatusCode.success

        value, _ = sess.get_attribute(ResourceAttribute.timeout_value)
        assert value == 5000

    def test_gpib_primary_address(self, mock_transport):
        mock_transport.connect()
        sess = AR488InstrSession(
            transport=mock_transport,
            resource_name="GPIB0::22::INSTR",
            primary_address=22,
        )
        value, status = sess.get_attribute(ResourceAttribute.gpib_primary_address)
        assert status == StatusCode.success
        assert value == 22

    def test_resource_name_attribute(self, mock_transport):
        mock_transport.connect()
        sess = AR488InstrSession(
            transport=mock_transport,
            resource_name="GPIB0::5::INSTR",
            primary_address=5,
        )
        value, status = sess.get_attribute(ResourceAttribute.resource_name)
        assert status == StatusCode.success
        assert value == "GPIB0::5::INSTR"

    def test_unsupported_attribute(self, mock_transport):
        mock_transport.connect()
        sess = AR488InstrSession(
            transport=mock_transport,
            resource_name="GPIB0::1::INSTR",
            primary_address=1,
        )
        # Use a real but unsupported-by-us attribute
        _, status = sess.get_attribute(ResourceAttribute.manufacturer_name)
        assert status == StatusCode.error_nonsupported_attribute


class TestSessionIO:
    """Test read/write through session."""

    def test_write_sets_address(self, mock_transport):
        mock_transport.connect()
        sess = AR488InstrSession(
            transport=mock_transport,
            resource_name="GPIB0::5::INSTR",
            primary_address=5,
        )
        count, status = sess.write(b"*IDN?\n")
        assert status == StatusCode.success
        assert count > 0
        # Verify address was set
        assert mock_transport._current_address == 5

    def test_read_response(self, mock_transport):
        mock_transport.connect()
        sess = AR488InstrSession(
            transport=mock_transport,
            resource_name="GPIB0::5::INSTR",
            primary_address=5,
        )
        sess.write(b"MEAS:VOLT:DC?\n")
        data, status = sess.read(1024)
        assert status == StatusCode.success
        assert b"5.43210" in data

    def test_clear(self, mock_transport):
        mock_transport.connect()
        sess = AR488InstrSession(
            transport=mock_transport,
            resource_name="GPIB0::1::INSTR",
            primary_address=1,
        )
        status = sess.clear()
        assert status == StatusCode.success

    def test_serial_poll(self, mock_transport):
        mock_transport.connect()
        sess = AR488InstrSession(
            transport=mock_transport,
            resource_name="GPIB0::1::INSTR",
            primary_address=1,
        )
        stb, status = sess.read_stb()
        assert status == StatusCode.success
        assert stb == 0  # default status byte

    def test_close(self, mock_transport):
        mock_transport.connect()
        sess = AR488InstrSession(
            transport=mock_transport,
            resource_name="GPIB0::1::INSTR",
            primary_address=1,
        )
        status = sess.close()
        assert status == StatusCode.success
