"""Tests for _services/_allego_core.py — mock stub verification."""

from __future__ import annotations

from unittest.mock import MagicMock, patch

from radiens_core._generated import allegoserver_pb2, common_pb2
from radiens_core._services._allego_core import (
    get_stim_params_proto,
    healthcheck_proto,
    restart_proto,
    set_record_state_proto,
)


class TestGetStimParamsProto:
    def test_calls_stub_with_standard_request(self) -> None:
        """Verify the service calls GetStimParams with a StandardRequest."""
        mock_pool = MagicMock()
        mock_channel = MagicMock()
        mock_pool.get_channel.return_value = mock_channel

        expected_reply = allegoserver_pb2.StimParamsReply()

        with patch("radiens_core._services._allego_core.allegoserver_pb2_grpc.AllegoCoreStub") as mock_stub_cls:
            mock_stub = MagicMock()
            mock_stub.GetStimParams.return_value = expected_reply
            mock_stub_cls.return_value = mock_stub

            result = get_stim_params_proto(mock_pool, "localhost:50051")

        mock_pool.get_channel.assert_called_once_with("localhost:50051")
        mock_stub_cls.assert_called_once_with(mock_channel)
        mock_stub.GetStimParams.assert_called_once()

        # Verify the request arg is a StandardRequest
        call_args = mock_stub.GetStimParams.call_args
        request = call_args[0][0]
        assert isinstance(request, common_pb2.StandardRequest)

        assert result is expected_reply


class TestHealthcheckProto:
    def test_calls_stub_with_standard_request(self) -> None:
        """Verify the service calls Healthcheck with a StandardRequest."""
        mock_pool = MagicMock()
        mock_channel = MagicMock()
        mock_pool.get_channel.return_value = mock_channel

        expected_reply = common_pb2.StandardReply()

        with patch("radiens_core._services._allego_core.allegoserver_pb2_grpc.AllegoLifecycleStub") as mock_stub_cls:
            mock_stub = MagicMock()
            mock_stub.Healthcheck.return_value = expected_reply
            mock_stub_cls.return_value = mock_stub

            result = healthcheck_proto(mock_pool, "localhost:50051")

        mock_pool.get_channel.assert_called_once_with("localhost:50051")
        mock_stub_cls.assert_called_once_with(mock_channel)
        mock_stub.Healthcheck.assert_called_once()

        # Verify the request arg is a StandardRequest
        call_args = mock_stub.Healthcheck.call_args
        request = call_args[0][0]
        assert isinstance(request, common_pb2.StandardRequest)

        assert result is expected_reply


class TestSetRecordStateProto:
    def test_calls_stub_with_record_request(self) -> None:
        """Verify the service calls SetRecordState with a SetRecordRequest."""
        mock_pool = MagicMock()
        mock_channel = MagicMock()
        mock_pool.get_channel.return_value = mock_channel

        # Create a sample SetRecordRequest
        test_request = allegoserver_pb2.SetRecordRequest()
        test_request.mode = allegoserver_pb2.R_ON

        expected_reply = common_pb2.StandardReply()

        with patch("radiens_core._services._allego_core.allegoserver_pb2_grpc.AllegoCoreStub") as mock_stub_cls:
            mock_stub = MagicMock()
            mock_stub.SetRecordState.return_value = expected_reply
            mock_stub_cls.return_value = mock_stub

            result = set_record_state_proto(mock_pool, "localhost:50051", test_request)

        mock_pool.get_channel.assert_called_once_with("localhost:50051")
        mock_stub_cls.assert_called_once_with(mock_channel)
        mock_stub.SetRecordState.assert_called_once_with(test_request)

        assert result is expected_reply


class TestRestartProto:
    def test_calls_stub_with_restart_request(self) -> None:
        """Verify the service calls Restart with a RestartRequest."""
        mock_pool = MagicMock()
        mock_channel = MagicMock()
        mock_pool.get_channel.return_value = mock_channel

        # Create a sample RestartRequest
        test_request = allegoserver_pb2.RestartRequest()
        test_request.mode = allegoserver_pb2.SMARTBOX_PRO

        expected_reply = common_pb2.StandardReply()

        with patch("radiens_core._services._allego_core.allegoserver_pb2_grpc.AllegoCoreStub") as mock_stub_cls:
            mock_stub = MagicMock()
            mock_stub.Restart.return_value = expected_reply
            mock_stub_cls.return_value = mock_stub

            result = restart_proto(mock_pool, "localhost:50051", test_request)

        mock_pool.get_channel.assert_called_once_with("localhost:50051")
        mock_stub_cls.assert_called_once_with(mock_channel)
        mock_stub.Restart.assert_called_once_with(test_request)

        assert result is expected_reply
