"""Configuration loading utilities for the Codex conversation logger."""

from __future__ import annotations

from dataclasses import dataclass, field
from datetime import timezone
from pathlib import Path
from typing import Any, Dict, Optional

import yaml


@dataclass
class RotationPolicy:
    window_seconds: int = 86400
    retention_days: Optional[int] = 30
    timezone: timezone = timezone.utc


@dataclass
class FlushPolicy:
    max_buffer_bytes: int = 1_000_000
    max_interval_seconds: int = 10


@dataclass
class ServerConfig:
    host: str = "127.0.0.1"
    port: int = 8421
    socket_path: Optional[Path] = None
    backlog: int = 100


@dataclass
class LoggerConfig:
    log_dir: Path = Path("/var/log/codex")
    tmp_suffix: str = ".tmp"
    filename_template: str = "codex-{stamp}.json"
    stamp_format: str = "%Y%m%d-%H%M%S"
    rotation: RotationPolicy = field(default_factory=RotationPolicy)
    flush: FlushPolicy = field(default_factory=FlushPolicy)
    server: ServerConfig = field(default_factory=ServerConfig)
    health_path: str = "/healthz"
    ingest_path: str = "/ingest"
    metrics_path: str = "/metrics"

    @property
    def log_dir_path(self) -> Path:
        return Path(self.log_dir)


def _load_yaml(path: Path) -> Dict[str, Any]:
    with path.open("r", encoding="utf-8") as handle:
        return yaml.safe_load(handle) or {}


def _merge_dataclass(dc_cls, data: Dict[str, Any]):
    kwargs = {}
    for field_obj in dc_cls.__dataclass_fields__.values():  # type: ignore[attr-defined]
        value = data.get(field_obj.name)
        if value is None:
            continue
        if hasattr(field_obj.type, "__dataclass_fields__"):
            merge_cls = field_obj.type
            kwargs[field_obj.name] = _merge_dataclass(merge_cls, value)
        else:
            kwargs[field_obj.name] = value
    return dc_cls(**kwargs)


def load_config(path: Optional[Path]) -> LoggerConfig:
    if path is None:
        return LoggerConfig()
    data = _load_yaml(path)
    return _merge_dataclass(LoggerConfig, data)

