"""Tests for doctor resource check (Phase 2 + Phase 4)."""

from __future__ import annotations

from unittest.mock import MagicMock

from ilum.core.kubernetes import KubeClient
from ilum.doctor.checks import CheckStatus, check_resources


class TestCheckResources:
    def test_ok_with_sufficient_resources(self) -> None:
        k8s = MagicMock(spec=KubeClient)
        k8s.get_cluster_resources.return_value = {
            "allocatable_memory_bytes": 16 * 1024 * 1024 * 1024,
            "allocatable_cpu_millicores": 8000,
            "node_count": 2,
        }
        result = check_resources(k8s, ["core", "ui"])
        assert result.status == CheckStatus.OK

    def test_warn_with_insufficient_resources(self) -> None:
        k8s = MagicMock(spec=KubeClient)
        k8s.get_cluster_resources.return_value = {
            "allocatable_memory_bytes": 4 * 1024 * 1024 * 1024,
            "allocatable_cpu_millicores": 2000,
            "node_count": 1,
        }
        result = check_resources(k8s, ["core", "ui", "mongodb", "kafka", "airflow", "trino"])
        assert result.status == CheckStatus.WARN

    def test_skip_when_cluster_unreachable(self) -> None:
        k8s = MagicMock(spec=KubeClient)
        k8s.get_cluster_resources.side_effect = Exception("unreachable")
        result = check_resources(k8s, ["core", "ui"])
        assert result.status in (CheckStatus.OK, CheckStatus.SKIP)

    def test_ok_with_no_modules(self) -> None:
        k8s = MagicMock(spec=KubeClient)
        k8s.get_cluster_resources.return_value = {
            "allocatable_memory_bytes": 8 * 1024 * 1024 * 1024,
            "allocatable_cpu_millicores": 4000,
            "node_count": 1,
        }
        result = check_resources(k8s, [])
        assert result.status == CheckStatus.OK


class TestParseMemory:
    def test_ki(self) -> None:
        assert KubeClient._parse_memory("16384Ki") == 16384 * 1024

    def test_mi(self) -> None:
        assert KubeClient._parse_memory("512Mi") == 512 * 1024 * 1024

    def test_gi(self) -> None:
        assert KubeClient._parse_memory("16Gi") == 16 * 1024 * 1024 * 1024

    def test_bytes(self) -> None:
        assert KubeClient._parse_memory("17179869184") == 17179869184


class TestParseCpu:
    def test_millicores(self) -> None:
        assert KubeClient._parse_cpu("4000m") == 4000

    def test_cores(self) -> None:
        assert KubeClient._parse_cpu("4") == 4000

    def test_fractional_cores(self) -> None:
        assert KubeClient._parse_cpu("0.5") == 500

    def test_nanocores(self) -> None:
        assert KubeClient._parse_cpu("2637031n") == 2

    def test_nanocores_large(self) -> None:
        assert KubeClient._parse_cpu("500000000n") == 500

    def test_microcores(self) -> None:
        assert KubeClient._parse_cpu("500000u") == 500
