"""Lecture de map.toml : la liste blanche des dotfiles."""

from __future__ import annotations

import os
import tomllib
from dataclasses import dataclass
from pathlib import Path

GLOBAL_EXCLUDES: list[str] = [
    "**/cache",
    "**/Cache",
    "**/caches",
    "**/logs",
    "**/*.log",
    "**/node_modules",
    "**/.DS_Store",
    "**/*.sock",
]


@dataclass(frozen=True)
class DotfileEntry:
    path: str
    secret: bool = False
    exclude: tuple[str, ...] = ()
    description: str = ""


def default_map_path() -> Path:
    env = os.environ.get("OSX_BACKUP_MAP")
    if env:
        return Path(env)
    return Path(__file__).resolve().parents[2] / "map.toml"


def _checked_path(raw_path: str) -> str:
    """`raw_path`, ou `ValueError` s'il sortait de $HOME.

    Les entrées sont des chemins **relatifs à $HOME** : un `path` absolu ou contenant `..`
    ferait viser `<dest>/<path>` — c'est-à-dire le fichier réel — puis supprimer l'original
    avant de le recopier.
    """
    parts = Path(raw_path).parts
    if Path(raw_path).is_absolute() or ".." in parts:
        raise ValueError(
            f"entrée de map.toml hors de $HOME (chemin absolu ou remontant) : {raw_path}"
        )
    return raw_path


def load_map(path: Path | None = None) -> list[DotfileEntry]:
    p = path or default_map_path()
    data = tomllib.loads(p.read_text(encoding="utf-8"))
    return [
        DotfileEntry(
            path=_checked_path(raw["path"]),
            secret=bool(raw.get("secret", False)),
            exclude=tuple(raw.get("exclude", [])),
            description=str(raw.get("description", "")),
        )
        for raw in data.get("dotfiles", [])
    ]
