"""Prometheus metric definitions for the OCR service.

`build_metrics(registry)` returns a fresh `OcrMetrics` instance bound to the
given `CollectorRegistry`. Production code calls it once at module load with
the default `REGISTRY`; tests pass a per-test `CollectorRegistry()` to keep
counter values isolated between cases (decision #3 on issue #652).
"""

from __future__ import annotations

from dataclasses import dataclass

from prometheus_client import CollectorRegistry, Counter, Gauge, Histogram


@dataclass(frozen=True)
class OcrMetrics:
    """Container for every custom OCR metric.

    Counters and gauges are immutable references to `prometheus_client`
    instances. Mutating them (`.inc()`, `.observe()`, `.set()`) is safe;
    rebinding the field on the dataclass is not — use `build_metrics` to get
    a new container.
    """

    ocr_jobs_total: Counter
    ocr_pages_total: Counter
    ocr_skipped_pages_total: Counter
    ocr_words_total: Counter
    ocr_illegible_words_total: Counter
    ocr_processing_seconds: Histogram
    ocr_training_runs_total: Counter
    ocr_model_accuracy: Gauge
    ocr_models_ready: Gauge


def build_metrics(registry: CollectorRegistry) -> OcrMetrics:
    """Create one OcrMetrics instance bound to `registry`."""
    return OcrMetrics(
        ocr_jobs_total=Counter(
            "ocr_jobs_total",
            "Number of OCR jobs processed, labelled by engine and script type.",
            ["engine", "script_type"],
            registry=registry,
        ),
        ocr_pages_total=Counter(
            "ocr_pages_total",
            "Number of pages successfully OCR'd, labelled by engine.",
            ["engine"],
            registry=registry,
        ),
        ocr_skipped_pages_total=Counter(
            "ocr_skipped_pages_total",
            "Number of pages skipped because the OCR engine raised.",
            registry=registry,
        ),
        ocr_words_total=Counter(
            "ocr_words_total",
            "Number of words recognized across all OCR blocks.",
            registry=registry,
        ),
        ocr_illegible_words_total=Counter(
            "ocr_illegible_words_total",
            "Number of words below the confidence threshold "
            "(replaced with [unleserlich]).",
            registry=registry,
        ),
        ocr_processing_seconds=Histogram(
            "ocr_processing_seconds",
            "OCR processing time per page (streaming) or per document (non-streaming).",
            ["engine"],
            registry=registry,
        ),
        ocr_training_runs_total=Counter(
            "ocr_training_runs_total",
            "Number of training runs, labelled by kind (recognition|segmentation) "
            "and outcome (success|error).",
            ["kind", "outcome"],
            registry=registry,
        ),
        ocr_model_accuracy=Gauge(
            "ocr_model_accuracy",
            "Latest model accuracy reported by a successful training run.",
            ["kind"],
            registry=registry,
        ),
        ocr_models_ready=Gauge(
            "ocr_models_ready",
            "1 once the lifespan startup has finished loading models, 0 before.",
            registry=registry,
        ),
    )
