"""publish — close the loop: make a sample kit loadable by SuperDirt.

ParVagues' custom kits live in `~/Work/Sound/Samples/<kit>/` and become playable
as `s "<kit>"` via a symlink in Dirt-Samples (325/508 of PLN's Dirt-Samples
entries are exactly this). The Foundry's last step links a freshly-cut kit so it
drops straight into a livecoding session — no manual `ln -s`.

    from engine.publish import link_kit, samples_root, dirt_samples
"""
from __future__ import annotations

import os
from dataclasses import dataclass
from pathlib import Path


def samples_root() -> Path:
    """Custom sample root SuperDirt kits live in. Override $FOUNDRY_SAMPLES."""
    return Path(os.environ.get("FOUNDRY_SAMPLES", str(Path.home() / "Work" / "Sound" / "Samples")))


def dirt_samples() -> Path:
    """The Dirt-Samples dir SuperDirt scans. Override $FOUNDRY_DIRT_SAMPLES."""
    return Path(os.environ.get(
        "FOUNDRY_DIRT_SAMPLES",
        str(Path.home() / ".local/share/SuperCollider/downloaded-quarks/Dirt-Samples"),
    ))


@dataclass
class LinkResult:
    kit: str
    src: Path           # the real kit dir (in Samples)
    link: Path          # the symlink in Dirt-Samples
    action: str         # "created" | "already-linked" | "repointed" | "skipped-real-dir"


def link_kit(kit: str, *, samples: Path | None = None, dirt: Path | None = None) -> LinkResult:
    """Symlink Dirt-Samples/<kit> → Samples/<kit> so `s "<kit>"` resolves.

    Idempotent. Refuses to clobber a *real* directory already at the target
    (we never delete what we didn't create) — that's surfaced, not overwritten.
    """
    samples = samples or samples_root()
    dirt = dirt or dirt_samples()
    src = (samples / kit).resolve()
    if not src.is_dir():
        raise FileNotFoundError(f"no kit dir to publish: {src}")
    dirt.mkdir(parents=True, exist_ok=True)
    link = dirt / kit

    if link.is_symlink():
        if link.resolve() == src:
            return LinkResult(kit, src, link, "already-linked")
        link.unlink()  # repoint a stale symlink (safe: it's a link, not data)
        link.symlink_to(src)
        return LinkResult(kit, src, link, "repointed")
    if link.exists():  # a real dir/file we didn't make — don't touch it
        return LinkResult(kit, src, link, "skipped-real-dir")
    link.symlink_to(src)
    return LinkResult(kit, src, link, "created")
