"""Racine du kit et découverte des CSV — pendant Python de `workspace.rs`.

Le hub Rust exporte `CSVKIT_ROOT` avant de lancer un micro-script, donc en
pratique la variable est toujours là. La remontée d'arborescence sert au cas
où le script est appelé à la main (`uv run -m csvkit_py.tools.profile`).
"""

from __future__ import annotations

import os
from pathlib import Path

MARKERS = ("tools", "python")


def find_root(start: Path | None = None) -> Path:
    """Résout la racine du kit, ou lève une erreur explicite."""
    env = os.environ.get("CSVKIT_ROOT")
    if env:
        root = Path(env)
        if not _is_root(root):
            raise RuntimeError(f"CSVKIT_ROOT pointe sur {root}, qui n'est pas la racine du kit")
        return root

    cwd = (start or Path.cwd()).resolve()
    for candidate in (cwd, *cwd.parents):
        if _is_root(candidate):
            return candidate

    raise RuntimeError(
        f"racine du kit introuvable depuis {cwd} — lance depuis le dépôt ou définis CSVKIT_ROOT"
    )


def _is_root(path: Path) -> bool:
    return all((path / m).is_dir() for m in MARKERS)


def sources_dir(root: Path) -> Path:
    return root / "sources"


def out_dir(root: Path) -> Path:
    return root / "out"


def find_csv(root: Path) -> list[Path]:
    """Liste les CSV de `sources/` puis `out/`, triés, dédupliqués.

    Même ordre que le hub Rust : les sources d'abord, les fichiers produits
    ensuite — ce sont les entrées possibles d'un chaînage.
    """
    found: list[Path] = []
    for directory in (sources_dir(root), out_dir(root)):
        if directory.is_dir():
            found.extend(sorted(p for p in directory.rglob("*.csv") if p.is_file()))
    return found
