"""Remote host metrics via Prometheus / node_exporter (stdlib urllib only).

The PostgreSQL instance is remote, so psutil cannot attribute its CPU/RAM
(spec 09 assumed a local instance). The database host runs Prometheus;
its base URL comes from the TRIBO_PROM_URL environment variable
(e.g. http://192.168.10.73:9090). Unset = monitoring disabled.
"""

from __future__ import annotations

import json
import logging
import os
import urllib.parse
import urllib.request

logger = logging.getLogger(__name__)

QUERY_STEP_S = 5
HTTP_TIMEOUT_S = 15
# rate() window must span at least two scrapes (15 s default interval)
CPU_QUERY = '100 * (1 - avg(rate(node_cpu_seconds_total{mode="idle"}[30s])))'
RAM_QUERY = "node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes"


def get_prom_url() -> str:
	return os.environ.get("TRIBO_PROM_URL", "")


def query_range(base_url: str, promql: str, start: float, end: float) -> list[float]:
	params = urllib.parse.urlencode({"query": promql, "start": start, "end": end, "step": QUERY_STEP_S})
	url = base_url.rstrip("/") + "/api/v1/query_range?" + params
	with urllib.request.urlopen(url, timeout=HTTP_TIMEOUT_S) as resp:
		data = json.load(resp)
	if data.get("status") != "success":
		raise RuntimeError(f"prometheus query failed: {data.get('errorType')}: {data.get('error')}")
	result = data["data"]["result"]
	if not result:
		return []
	return [float(v) for _, v in result[0]["values"]]


def host_window_metrics(base_url: str, start: float, end: float) -> dict | None:
	"""CPU/RAM of the monitored host over [start, end] wall-clock seconds.

	Returns None (with a warning) on any failure - monitoring is best-effort
	and must never fail the owning task.
	"""
	try:
		if end - start < 2 * QUERY_STEP_S:
			end = start + 2 * QUERY_STEP_S
		cpu = query_range(base_url, CPU_QUERY, start, end)
		ram = query_range(base_url, RAM_QUERY, start, end)
		if not cpu or not ram:
			logger.warning("prometheus returned no samples for the window (expected condition: short window or scrape lag)")
			return None
		return {
			"host_cpu_avg_pct": round(sum(cpu) / len(cpu), 1),
			"host_cpu_max_pct": round(max(cpu), 1),
			"host_ram_used_baseline_mb": round(ram[0] / 1048576),
			"host_ram_used_peak_mb": round(max(ram) / 1048576),
			"host_ram_used_delta_mb": round((max(ram) - ram[0]) / 1048576),
		}
	except Exception:
		logger.warning("host metrics collection skipped (prometheus unreachable or query failed)", exc_info=True)
		return None
