"""Global configuration management for gaol."""

from __future__ import annotations

import os
from pathlib import Path
from typing import Annotated

import yaml
from pydantic import BaseModel, Field


def _get_user_home() -> Path:
    """Get the real user's home directory, even under sudo."""
    sudo_user = os.environ.get("SUDO_USER")
    if sudo_user:
        import pwd

        try:
            return Path(pwd.getpwnam(sudo_user).pw_dir)
        except KeyError:
            pass
    return Path.home()


def get_config_dir() -> Path:
    """Get the configuration directory."""
    xdg_config = os.environ.get("XDG_CONFIG_HOME")
    if xdg_config:
        config_dir = Path(xdg_config) / "gaol"
    else:
        config_dir = _get_user_home() / ".config" / "gaol"
    config_dir.mkdir(parents=True, exist_ok=True)
    return config_dir


def get_data_dir() -> Path:
    """Get the data directory."""
    xdg_data = os.environ.get("XDG_DATA_HOME")
    if xdg_data:
        data_dir = Path(xdg_data) / "gaol"
    else:
        data_dir = _get_user_home() / ".local" / "share" / "gaol"
    data_dir.mkdir(parents=True, exist_ok=True)
    return data_dir


class RuntimeConfig(BaseModel):
    """Configuration for a specific runtime."""

    enabled: bool = True
    default_image: str | None = None


class Config(BaseModel):
    """Global gaol configuration."""

    default_runtime: Annotated[str, Field(default="docker")]
    default_distro: Annotated[str, Field(default="trixie")]
    profile_dirs: Annotated[
        list[str],
        Field(
            default_factory=lambda: [str(get_config_dir() / "profiles"), "./profiles"],
            description="Directories to search for profile definitions",
        ),
    ]
    runtimes: Annotated[
        dict[str, RuntimeConfig],
        Field(
            default_factory=lambda: {
                "docker": RuntimeConfig(),
                "nspawn": RuntimeConfig(),
                "libvirt": RuntimeConfig(),
            }
        ),
    ]

    @classmethod
    def load(cls) -> Config:
        """Load configuration from file or return defaults."""
        config_file = get_config_dir() / "config.yaml"
        if config_file.exists():
            with open(config_file) as f:
                data = yaml.safe_load(f) or {}
            return cls(**data)
        return cls()

    def save(self) -> None:
        """Save configuration to file."""
        config_file = get_config_dir() / "config.yaml"
        with open(config_file, "w") as f:
            yaml.dump(self.model_dump(), f, default_flow_style=False)


# Global configuration instance
_config: Config | None = None


def get_config() -> Config:
    """Get the global configuration instance."""
    global _config
    if _config is None:
        _config = Config.load()
    return _config
