"""Metrics emitter for structured log emission.

``MetricsEmitter`` accepts ``MetricEntry`` objects and emits them as
structured log entries via ``structlog``.  Local-mode emission is the
default; Prometheus export is a future extension gated behind a
configuration flag.

Based on Forgejo issue #579.
"""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

import structlog

if TYPE_CHECKING:
    from cleveragents.config.settings import Settings
    from cleveragents.domain.models.observability.metrics import MetricEntry

logger = structlog.get_logger(__name__)


class MetricsEmitter:
    """Emits ``MetricEntry`` objects as structured log entries.

    Attributes:
        _enabled: Whether metric emission is active.
        _prometheus_enabled: Whether Prometheus export is enabled.
    """

    def __init__(
        self,
        *,
        enabled: bool = True,
        prometheus_enabled: bool = False,
    ) -> None:
        """Initialise the metrics emitter.

        Args:
            enabled: Master switch for metric emission.
            prometheus_enabled: Enable Prometheus export (future).
        """
        self._enabled = enabled
        self._prometheus_enabled = prometheus_enabled

    @classmethod
    def from_settings(cls, settings: Settings) -> MetricsEmitter:
        """Create a ``MetricsEmitter`` from application settings.

        Args:
            settings: Application settings instance.

        Returns:
            A configured ``MetricsEmitter``.
        """
        return cls(
            enabled=getattr(settings, "metrics_enabled", True),
            prometheus_enabled=getattr(settings, "metrics_export_prometheus", False),
        )

    @property
    def enabled(self) -> bool:
        """Whether metric emission is active."""
        return self._enabled

    @enabled.setter
    def enabled(self, value: bool) -> None:
        """Set the enabled state."""
        self._enabled = value

    @property
    def prometheus_enabled(self) -> bool:
        """Whether Prometheus export is enabled."""
        return self._prometheus_enabled

    def emit(self, entry: MetricEntry) -> None:
        """Emit a single metric entry as a structured log event.

        When ``enabled`` is ``False``, this is a no-op.

        Args:
            entry: The metric entry to emit.
        """
        if not self._enabled:
            return

        log_data: dict[str, Any] = {
            "metric_key": str(entry.key),
            "metric_value": entry.value,
            "plan_id": entry.plan_id,
            "timestamp": entry.timestamp.isoformat(),
        }
        if entry.metric_type is not None:
            log_data["metric_type"] = str(entry.metric_type)
        if entry.labels:
            log_data["labels"] = entry.labels

        logger.info("metric.recorded", **log_data)

    def emit_batch(self, entries: list[MetricEntry]) -> int:
        """Emit multiple metric entries.

        Args:
            entries: List of metric entries to emit.

        Returns:
            Number of entries emitted (0 when disabled).
        """
        if not self._enabled:
            return 0

        for entry in entries:
            self.emit(entry)
        return len(entries)
