"""
This program has been developed by students from the bachelor Computer Science at Utrecht
University within the Software Project course.
© Copyright Utrecht University (Department of Information and Computing Sciences)
"""

from unittest.mock import AsyncMock, MagicMock

import pytest
import zmq

from control_backend.agents.perception.vad_agent import SocketPoller


@pytest.fixture
def socket():
    return AsyncMock()


@pytest.mark.asyncio
async def test_socket_poller_with_data(socket, mocker):
    socket_data = b"test"
    socket.recv.return_value = socket_data

    mock_poller: MagicMock = mocker.patch("control_backend.agents.perception.vad_agent.azmq.Poller")
    mock_poller.return_value.poll = AsyncMock(return_value=[(socket, zmq.POLLIN)])

    poller = SocketPoller(socket)
    # Calling `poll` twice to be able to check that the poller is reused
    await poller.poll()
    data = await poller.poll()

    assert data == socket_data

    # Ensure that the poller was reused
    mock_poller.assert_called_once_with()
    mock_poller.return_value.register.assert_called_once_with(socket, zmq.POLLIN)

    assert socket.recv.call_count == 2


@pytest.mark.asyncio
async def test_socket_poller_no_data(socket, mocker):
    mock_poller: MagicMock = mocker.patch("control_backend.agents.perception.vad_agent.azmq.Poller")
    mock_poller.return_value.poll = AsyncMock(return_value=[])

    poller = SocketPoller(socket)
    data = await poller.poll()

    assert data is None

    socket.recv.assert_not_called()
