"""Tests for AllegoClient healthcheck method."""

from __future__ import annotations

from unittest.mock import MagicMock, patch

import pytest

from radiens_core import AllegoClient
from radiens_core._generated import common_pb2
from radiens_core.exceptions import RadiensError
from radiens_core.models.common import ServiceEndpoint

_FAKE_ADDRESSES: dict[str, str] = {
    ServiceEndpoint.ALLEGO_CORE: "localhost:50051",
    ServiceEndpoint.ALLEGO_LIFECYCLE: "localhost:50051",
    ServiceEndpoint.ALLEGO_PCACHE: "localhost:50052",
}


def _make_client() -> AllegoClient:
    """Create an AllegoClient with discovery mocked out."""
    with patch.object(AllegoClient, "_discover", return_value=dict(_FAKE_ADDRESSES)):
        return AllegoClient()


class TestHealthcheck:
    def test_healthcheck_success(self) -> None:
        """Test successful healthcheck call."""
        mock_pool = MagicMock()
        mock_channel = MagicMock()
        mock_pool.get_channel.return_value = mock_channel

        # Mock successful response
        expected_reply = common_pb2.StandardReply()
        expected_reply.errMsg = ""  # Empty error message indicates success

        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

            client = _make_client()
            client._pool = mock_pool  # Inject mock pool
            # Should not raise any exception
            client.healthcheck()

        mock_pool.get_channel.assert_called_once_with(client._core_address)
        mock_stub_cls.assert_called_once_with(mock_channel)
        mock_stub.Healthcheck.assert_called_once()

    def test_healthcheck_failure(self) -> None:
        """Test healthcheck call with server error."""
        mock_pool = MagicMock()
        mock_channel = MagicMock()
        mock_pool.get_channel.return_value = mock_channel

        # Mock error response
        expected_reply = common_pb2.StandardReply()
        expected_reply.errMsg = "Connection timeout"

        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

            client = _make_client()
            client._pool = mock_pool  # Inject mock pool
            with pytest.raises(RadiensError, match="Health check failed: Connection timeout"):
                client.healthcheck()
