"""Configuration loading (TOML) for the relay."""
from __future__ import annotations

import os
import tomllib
from dataclasses import dataclass, field, fields
from pathlib import Path

ENV_RELAY_TOKEN = "AUTOTRANSFER_RELAY_TOKEN"


class ConfigError(Exception):
    pass


@dataclass
class LoggingConfig:
    level: str = "INFO"
    file: str = ""


@dataclass
class RelayConfig:
    host: str = "0.0.0.0"
    port: int = 8888
    auth_token: str = ""
    data_dir: str = "relay_data"
    ssl_cert_path: str = ""
    ssl_key_path: str = ""
    max_chunk_mb: int = 64
    retention_hours: int = 72

    def validate(self) -> list[str]:
        errors = []
        if not self.auth_token:
            errors.append(f"auth token is required (--token or ${ENV_RELAY_TOKEN})")
        elif len(self.auth_token) < 12:
            errors.append("auth token must be at least 12 characters")
        if not (1 <= int(self.port) <= 65535):
            errors.append("port must be between 1 and 65535")
        if bool(self.ssl_cert_path) != bool(self.ssl_key_path):
            errors.append("--cert and --key must be given together")
        for p in (self.ssl_cert_path, self.ssl_key_path):
            if p and not Path(p).exists():
                errors.append(f"file not found: {p}")
        return errors


@dataclass
class LoadedConfig:
    settings: RelayConfig
    logging: LoggingConfig = field(default_factory=LoggingConfig)


def load_config(path: str, role: str) -> LoadedConfig:
    if role != "relay":
        raise ConfigError(f"unsupported role: {role}")
    try:
        with open(path, "rb") as fh:
            data = tomllib.load(fh)
    except FileNotFoundError:
        raise ConfigError(f"config file not found: {path}")
    except tomllib.TOMLDecodeError as exc:
        raise ConfigError(f"invalid TOML in {path}: {exc}")

    def build(cls, section):
        known = {f.name for f in fields(cls)}
        unknown = set(section) - known
        if unknown:
            raise ConfigError(f"unknown keys {sorted(unknown)} in [{cls.__name__}]")
        return cls(**section)

    settings = build(RelayConfig, data.get("relay", {}))
    if not settings.auth_token:
        settings.auth_token = os.environ.get(ENV_RELAY_TOKEN, "")
    return LoadedConfig(settings, build(LoggingConfig, data.get("logging", {})))
