# ruff: noqa: INP001
"""Unit tests for system_health service helpers.

All tests are pure-Python — no gateway connection required.
"""

from __future__ import annotations

from datetime import datetime, timedelta

import pytest

from app.services.openclaw.system_health import (
    HealthSnapshot,
    HealthHistory,
    parse_health_response,
)


# ---------------------------------------------------------------------------
# Fixtures
# ---------------------------------------------------------------------------

FIXTURE_FULL = {
    "cpu": {"usage": 45.2, "cores": 8, "loadAvg": [1.2, 1.5, 1.8]},
    "memory": {"used": 4_294_967_296, "total": 16_777_216_000, "percent": 25.6},
    "disk": {"used": 50_000_000_000, "total": 500_000_000_000, "percent": 10.0},
    "uptime": 86400,
    "platform": "linux",
    "hostname": "gateway-host",
}

FIXTURE_ALT_KEYS = {
    "cpuUsage": 33.3,
    "memUsed": 2_000_000_000,
    "memTotal": 8_000_000_000,
    "diskUsed": 100_000_000_000,
    "diskTotal": 1_000_000_000_000,
    "uptimeSeconds": 3600,
}

FIXTURE_MINIMAL = {"uptime": 120}

FIXTURE_EMPTY = {}
FIXTURE_NONE = None


# ---------------------------------------------------------------------------
# parse_health_response
# ---------------------------------------------------------------------------

class TestParseHealthResponse:

    def test_full_response_parsed(self):
        snap = parse_health_response(FIXTURE_FULL)
        assert isinstance(snap, HealthSnapshot)

    def test_cpu_percent(self):
        snap = parse_health_response(FIXTURE_FULL)
        assert snap.cpu_pct == pytest.approx(45.2)

    def test_memory_percent(self):
        snap = parse_health_response(FIXTURE_FULL)
        assert snap.memory_pct == pytest.approx(25.6)

    def test_disk_percent(self):
        snap = parse_health_response(FIXTURE_FULL)
        assert snap.disk_pct == pytest.approx(10.0)

    def test_uptime_seconds(self):
        snap = parse_health_response(FIXTURE_FULL)
        assert snap.uptime_seconds == 86400

    def test_hostname(self):
        snap = parse_health_response(FIXTURE_FULL)
        assert snap.hostname == "gateway-host"

    def test_alt_key_cpu(self):
        snap = parse_health_response(FIXTURE_ALT_KEYS)
        assert snap.cpu_pct == pytest.approx(33.3)

    def test_alt_key_memory_computed(self):
        snap = parse_health_response(FIXTURE_ALT_KEYS)
        # 2GB / 8GB = 25%
        assert snap.memory_pct == pytest.approx(25.0, abs=1)

    def test_alt_key_disk_computed(self):
        snap = parse_health_response(FIXTURE_ALT_KEYS)
        # 100GB / 1000GB = 10%
        assert snap.disk_pct == pytest.approx(10.0, abs=1)

    def test_alt_key_uptime(self):
        snap = parse_health_response(FIXTURE_ALT_KEYS)
        assert snap.uptime_seconds == 3600

    def test_minimal_response(self):
        snap = parse_health_response(FIXTURE_MINIMAL)
        assert snap.uptime_seconds == 120
        assert snap.cpu_pct is None
        assert snap.memory_pct is None

    def test_empty_response(self):
        snap = parse_health_response(FIXTURE_EMPTY)
        assert snap.cpu_pct is None
        assert snap.memory_pct is None
        assert snap.uptime_seconds is None

    def test_none_response(self):
        snap = parse_health_response(FIXTURE_NONE)
        assert snap is not None  # always returns a snapshot
        assert snap.cpu_pct is None

    def test_recorded_at_is_set(self):
        snap = parse_health_response(FIXTURE_FULL)
        assert isinstance(snap.recorded_at, datetime)


# ---------------------------------------------------------------------------
# HealthHistory
# ---------------------------------------------------------------------------

class TestHealthHistory:

    def _make_snap(self, offset_hours: float = 0) -> HealthSnapshot:
        from app.core.time import utcnow
        snap = parse_health_response(FIXTURE_FULL)
        snap.recorded_at = utcnow() - timedelta(hours=offset_hours)
        return snap

    def test_add_snapshot(self):
        history = HealthHistory()
        history.add("gw-1", self._make_snap())
        assert len(history.get("gw-1")) == 1

    def test_multiple_snapshots(self):
        history = HealthHistory()
        for _ in range(5):
            history.add("gw-1", self._make_snap())
        assert len(history.get("gw-1")) == 5

    def test_old_snapshots_pruned(self):
        history = HealthHistory(window_hours=24)
        # Add a snapshot 25 hours old
        old = self._make_snap(offset_hours=25)
        history.add("gw-1", old)
        # Add a recent snapshot
        history.add("gw-1", self._make_snap())
        snaps = history.get("gw-1")
        assert len(snaps) == 1  # old one pruned

    def test_different_gateways_isolated(self):
        history = HealthHistory()
        history.add("gw-1", self._make_snap())
        history.add("gw-2", self._make_snap())
        assert len(history.get("gw-1")) == 1
        assert len(history.get("gw-2")) == 1

    def test_unknown_gateway_returns_empty(self):
        history = HealthHistory()
        assert history.get("nonexistent") == []

    def test_snapshots_ordered_oldest_first(self):
        history = HealthHistory()
        newer = self._make_snap(offset_hours=0)
        older = self._make_snap(offset_hours=1)
        history.add("gw-1", newer)
        history.add("gw-1", older)
        snaps = history.get("gw-1")
        # oldest first
        assert snaps[0].recorded_at <= snaps[1].recorded_at

    def test_latest_snapshot(self):
        history = HealthHistory()
        old = self._make_snap(offset_hours=2)
        new = self._make_snap(offset_hours=0)
        history.add("gw-1", old)
        history.add("gw-1", new)
        latest = history.latest("gw-1")
        assert latest is not None
        assert latest.recorded_at >= old.recorded_at

    def test_latest_none_when_empty(self):
        history = HealthHistory()
        assert history.latest("gw-1") is None
