"""Collector configuration — layered, global-defaults-first (CF-02 ethos).

Every knob has a global default; the environment overrides per deployment, and
finer-grained overrides (per OpenObserve stream, e.g. retention) happen on the
backend later. Nothing is hardcoded into the app: ``CollectorConfig.from_env``
is the single resolution point. Read with the ``MGF_LOGSHIP_`` prefix.
"""

from __future__ import annotations

import os
from dataclasses import dataclass
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from collections.abc import Mapping

__all__ = ["CollectorConfig"]

_PREFIX = "MGF_LOGSHIP_"


@dataclass(frozen=True, slots=True)
class CollectorConfig:
    """Resolved collector settings. Defaults are the federation-wide globals."""

    backend: str = "sqlite"  # "sqlite" (store-now/stub) | "openobserve" (forward)
    token: str | None = None  # inbound /ingest + /stats bearer (None = open)
    db_path: str = "logship.db"  # sqlite store, or the spool when forwarding
    # OpenObserve backend
    openobserve_url: str = "http://localhost:5080"
    openobserve_org: str = "default"
    log_stream: str = "mgf_logs"
    stats_stream: str = "mgf_logstats"
    openobserve_token: str | None = None
    openobserve_user: str | None = None
    openobserve_password: str | None = None
    # operational knobs (global defaults; overridable per deployment)
    flush_interval_s: float = 30.0  # 0 disables the in-app spool flusher
    retention_days: int = 30  # the global retention default (applied at the OO stream)

    @classmethod
    def from_env(cls, env: Mapping[str, str] | None = None) -> CollectorConfig:
        e = os.environ if env is None else env

        def s(key: str, default: str | None) -> str | None:
            return e.get(_PREFIX + key, default)

        return cls(
            backend=s("BACKEND", "sqlite") or "sqlite",
            token=s("TOKEN", None),
            db_path=s("DB_PATH", "logship.db") or "logship.db",
            openobserve_url=s("OPENOBSERVE_URL", "http://localhost:5080") or "http://localhost:5080",
            openobserve_org=s("OPENOBSERVE_ORG", "default") or "default",
            log_stream=s("LOG_STREAM", "mgf_logs") or "mgf_logs",
            stats_stream=s("STATS_STREAM", "mgf_logstats") or "mgf_logstats",
            openobserve_token=s("OPENOBSERVE_TOKEN", None),
            openobserve_user=s("OPENOBSERVE_USER", None),
            openobserve_password=s("OPENOBSERVE_PASSWORD", None),
            flush_interval_s=float(s("FLUSH_INTERVAL_S", "30") or "30"),
            retention_days=int(s("RETENTION_DAYS", "30") or "30"),
        )
