"""
Tests for brain_watchdog.main.

Module-level env vars are required at import time; set them before the first
import of the module so tests can run without a real control-plane.
"""
import importlib.util
import os
import time
from unittest.mock import patch

os.environ.setdefault("CONTROL_PLANE_URL", "http://test-cp:8080")
os.environ.setdefault("TG_TOKEN", "test_token")
os.environ.setdefault("TG_CHAT_ID", "12345")

import brain_watchdog.main as bwm


def test_package_importable():
    spec = importlib.util.find_spec("brain_watchdog")
    assert spec is not None


def test_check_ok_fresh():
    now = time.time()
    with patch.object(bwm, "http_get", return_value=(200, {"last_update": now - 10})):
        ok, reason = bwm.check()
    assert ok
    assert "ok" in reason


def test_check_fail_stale():
    now = time.time()
    stale_ts = now - (bwm.STALE_THRESHOLD + 120)
    with patch.object(bwm, "http_get", return_value=(200, {"last_update": stale_ts})):
        ok, reason = bwm.check()
    assert not ok
    assert "stale" in reason


def test_check_fail_unreachable():
    with patch.object(bwm, "http_get", return_value=(None, None)):
        ok, reason = bwm.check()
    assert not ok
    assert "unreachable" in reason


def test_check_fail_http_error():
    with patch.object(bwm, "http_get", return_value=(503, None)):
        ok, reason = bwm.check()
    assert not ok
    assert "503" in reason


def test_check_fail_missing_last_update():
    with patch.object(bwm, "http_get", return_value=(200, {"other": "data"})):
        ok, reason = bwm.check()
    assert not ok
    assert "last_update" in reason


def test_check_fail_unparseable_timestamp():
    with patch.object(bwm, "http_get", return_value=(200, {"last_update": "not-a-number"})):
        ok, reason = bwm.check()
    assert not ok
    assert "parseable" in reason


# ---------- Prometheus alert polling ----------

SAMPLE_PROM_RESPONSE = {
    "status": "success",
    "data": {
        "alerts": [
            {
                "labels": {"alertname": "NodeDown", "node": "piha"},
                "annotations": {"summary": "Node is down", "description": ""},
                "state": "firing",
                "activeAt": "2026-06-30T10:00:00Z",
                "value": "0e+00",
            },
            {
                "labels": {"alertname": "HighLoad", "node": "solaria"},
                "annotations": {"summary": "High CPU", "description": "CPU above 90%"},
                "state": "pending",
                "activeAt": "2026-06-30T10:01:00Z",
                "value": "0e+00",
            },
        ]
    },
}


def test_check_prometheus_alerts_disabled(monkeypatch):
    monkeypatch.setattr(bwm, "PROMETHEUS_URL", "")
    assert bwm.check_prometheus_alerts() == []


def test_check_prometheus_alerts_parses_firing(monkeypatch):
    monkeypatch.setattr(bwm, "PROMETHEUS_URL", "http://prom:9090")
    with patch.object(bwm, "http_get", return_value=(200, SAMPLE_PROM_RESPONSE)):
        result = bwm.check_prometheus_alerts()
    assert len(result) == 1
    assert result[0]["alertname"] == "NodeDown"
    assert result[0]["node"] == "piha"
    assert result[0]["key"] == "NodeDown:piha"
    assert result[0]["summary"] == "Node is down"


def test_check_prometheus_alerts_unreachable(monkeypatch):
    monkeypatch.setattr(bwm, "PROMETHEUS_URL", "http://prom:9090")
    with patch.object(bwm, "http_get", return_value=(None, None)):
        assert bwm.check_prometheus_alerts() == []


def test_prometheus_debounce_no_duplicate(monkeypatch):
    monkeypatch.setattr(bwm, "PROMETHEUS_URL", "http://prom:9090")
    firing = [
        {
            "key": "NodeDown:piha",
            "alertname": "NodeDown",
            "node": "piha",
            "summary": "down",
            "description": "",
        }
    ]
    with patch.object(bwm, "check_prometheus_alerts", return_value=firing):
        with patch.object(bwm, "send_telegram", return_value=True) as mock_tg:
            state: dict = {}
            bwm.handle_prometheus_alerts(state)
            assert mock_tg.call_count == 1
            assert "NodeDown:piha" in state["prom_alerted"]

            # Same alert still firing — debounce must suppress second send
            bwm.handle_prometheus_alerts(state)
            assert mock_tg.call_count == 1


def test_prometheus_debounce_recovery(monkeypatch):
    monkeypatch.setattr(bwm, "PROMETHEUS_URL", "http://prom:9090")
    state = {
        "prom_alerted": {
            "NodeDown:piha": {"alertname": "NodeDown", "node": "piha"}
        }
    }
    with patch.object(bwm, "check_prometheus_alerts", return_value=[]):
        with patch.object(bwm, "send_telegram", return_value=True) as mock_tg:
            bwm.handle_prometheus_alerts(state)

    assert mock_tg.call_count == 1
    call_text = mock_tg.call_args[0][0]
    assert "✅" in call_text
    assert "NodeDown" in call_text
    assert "NodeDown:piha" not in state["prom_alerted"]
