"""Prometheus metrics (OBS-02).

All metrics live in the default global REGISTRY so that /metrics picks them up
without extra wiring. Counters are incremented from pipeline.fetch_and_store
and the fetcher chain.
"""
from __future__ import annotations

from prometheus_client import Counter, Histogram

FETCH_TOTAL = Counter(
    "govcrawler_fetch_total",
    "Fetch attempts by outcome",
    labelnames=("site_id", "column_id", "strategy", "outcome"),  # outcome: ready|failed|skipped|challenge
)

FETCH_DURATION = Histogram(
    "govcrawler_fetch_duration_seconds",
    "Fetch duration per attempt",
    labelnames=("site_id", "column_id", "strategy"),
    buckets=(0.1, 0.3, 1, 3, 10, 30, 60, 120),
)

HTTP_BLOCK_TOTAL = Counter(
    "govcrawler_http_block_total",
    "HTTP 412/403/429 responses by site",
    labelnames=("site_id", "status"),
)

BROWSER_LAUNCHES = Counter(
    "govcrawler_browser_launches_total",
    "Playwright Chromium launches (Cookie pool miss cost proxy)",
    labelnames=("site_id",),
)

ARTICLES_NEW = Counter(
    "govcrawler_articles_new_total",
    "Articles newly persisted to DB",
    labelnames=("site_id", "column_id"),
)


def record_fetch(
    *,
    site_id: str,
    column_id: str,
    strategy: str,
    outcome: str,
    duration_ms: int,
    http_status: int | None = None,
) -> None:
    FETCH_TOTAL.labels(site_id=site_id, column_id=column_id, strategy=strategy, outcome=outcome).inc()
    FETCH_DURATION.labels(site_id=site_id, column_id=column_id, strategy=strategy).observe(duration_ms / 1000.0)
    if http_status in (403, 412, 429):
        HTTP_BLOCK_TOTAL.labels(site_id=site_id, status=str(http_status)).inc()
    if outcome == "ready":
        ARTICLES_NEW.labels(site_id=site_id, column_id=column_id).inc()


def record_browser_launch(site_id: str) -> None:
    BROWSER_LAUNCHES.labels(site_id=site_id).inc()
