"""Tests for NodeAgent._check_control_plane_health() transition-only emission.

Regression coverage for the event-flood fix: the VPS control-plane HTTP probe
used to emit service_healthy every single cycle it was reachable, which was
part of the same flood as check_containers()'s per-service confirmation.
"""
from __future__ import annotations

from unittest.mock import MagicMock

import node_agent


def run_probe(agent, monkeypatch, *, status=200, raise_exc=None):
    """Run _check_control_plane_health() with urlopen mocked, capturing emitted events."""
    emitted = []

    def fake_emit(event_type, severity, service, message, payload=None):
        emitted.append((event_type, severity, service, message, payload or {}))

    monkeypatch.setattr(agent, "emit_event", fake_emit)

    if raise_exc is not None:
        def fake_urlopen(*a, **kw):
            raise raise_exc
    else:
        resp = MagicMock()
        resp.status = status

        def fake_urlopen(*a, **kw):
            return resp

    monkeypatch.setattr("urllib.request.urlopen", fake_urlopen)
    agent._check_control_plane_health()
    return emitted


def test_reachable_emits_service_healthy(agent, monkeypatch):
    events = run_probe(agent, monkeypatch, status=200)
    assert len(events) == 1
    assert events[0][0] == "service_healthy"
    assert events[0][2] == "control-plane"


def test_reachable_second_cycle_is_silent(agent, monkeypatch):
    run_probe(agent, monkeypatch, status=200)
    events = run_probe(agent, monkeypatch, status=200)
    assert events == []


def test_unreachable_reemits_service_unhealthy_every_cycle(agent, monkeypatch):
    """service_unhealthy is a real fault signal — must stay unconditional."""
    run_probe(agent, monkeypatch, status=200)
    events = run_probe(agent, monkeypatch, raise_exc=OSError("connection refused"))
    assert events[0][0] == "service_unhealthy"
    events = run_probe(agent, monkeypatch, raise_exc=OSError("connection refused"))
    assert events[0][0] == "service_unhealthy"


def test_recovery_after_unreachable_reemits_service_healthy(agent, monkeypatch):
    run_probe(agent, monkeypatch, raise_exc=OSError("connection refused"))
    events = run_probe(agent, monkeypatch, status=200)
    assert len(events) == 1
    assert events[0][0] == "service_healthy"
