"""Glue checks for the metrics the quality-gate publishes."""

from __future__ import annotations

import os
from pathlib import Path

import requests
import yaml


VM_URL = os.environ.get("VM_URL", "http://victoria-metrics-single-server:8428").rstrip("/")
CONFIG_PATH = Path(__file__).with_name("config.yaml")


def _load_config() -> dict:
    with CONFIG_PATH.open("r", encoding="utf-8") as handle:
        return yaml.safe_load(handle) or {}


def _query(promql: str) -> list[dict]:
    response = requests.get(f"{VM_URL}/api/v1/query", params={"query": promql}, timeout=10)
    response.raise_for_status()
    payload = response.json()
    return payload.get("data", {}).get("result", [])


def _expected_tasks() -> list[dict]:
    cfg = _load_config()
    tasks = [
        _normalize_task(item, cfg)
        for item in cfg.get("ariadne_schedule_tasks", [])
    ]
    assert tasks, "No Ariadne schedule tasks configured"
    return tasks


def _normalize_task(item: object, cfg: dict) -> dict:
    if isinstance(item, str):
        return {
            "task": item,
            "check_last_success": True,
            "max_success_age_hours": cfg.get("max_success_age_hours", 48),
        }
    if isinstance(item, dict):
        normalized = dict(item)
        normalized.setdefault("check_last_success", True)
        normalized.setdefault("max_success_age_hours", cfg.get("max_success_age_hours", 48))
        return normalized
    raise TypeError(f"Unsupported Ariadne schedule task config entry: {item!r}")


def _tracked_tasks(tasks: list[dict]) -> list[dict]:
    tracked = [item for item in tasks if item.get("check_last_success")]
    assert tracked, "No Ariadne schedule tasks are marked for success tracking"
    return tracked


def _task_regex(tasks: list[dict]) -> str:
    return "|".join(item["task"] for item in tasks)


def test_ariadne_schedule_metrics_present():
    tasks = _expected_tasks()
    selector = _task_regex(tasks)
    series = _query(f'ariadne_schedule_next_run_timestamp_seconds{{task=~"{selector}"}}')
    seen = {item.get("metric", {}).get("task") for item in series}
    missing = [item["task"] for item in tasks if item["task"] not in seen]
    assert not missing, f"Missing Ariadne schedule metrics for: {', '.join(missing)}"


def test_ariadne_schedule_success_and_status_metrics_present():
    tasks = _tracked_tasks(_expected_tasks())
    selector = _task_regex(tasks)

    success = _query(f'ariadne_schedule_last_success_timestamp_seconds{{task=~"{selector}"}}')
    status = _query(f'ariadne_schedule_last_status{{task=~"{selector}"}}')

    success_tasks = {item.get("metric", {}).get("task") for item in success}
    status_tasks = {item.get("metric", {}).get("task") for item in status}
    expected = {item["task"] for item in tasks}

    missing_success = sorted(expected - success_tasks)
    missing_status = sorted(expected - status_tasks)

    assert not missing_success, f"Missing Ariadne success metrics for: {', '.join(missing_success)}"
    assert not missing_status, f"Missing Ariadne status metrics for: {', '.join(missing_status)}"
