#!/usr/bin/env python3
"""RETIRED 2026-06-11.

One-shot already executed on 2026-06-10. ``gen_sublocations.py`` subsumes this
tool's forward purpose and redefines registry ``source_sha256`` semantics from
plate hashes to bible-description hashes. Leaving this file live would
re-introduce plate-hash stamps: two writers, one file, two meanings.
"""

"""One-shot migration: rename a location's ``station`` probe refs into the
locked ``sublocation`` convention, write a two-hash lineage sidecar per ref,
and write the allowed-sublocation registry (``base/location.json``). REC-111
PR-3.

The data move and the code that reads the new layout land in the SAME phase, so
live code and on-disk layout never disagree across the boundary.

Idempotent: a completed migration re-runs as a no-op (prints the summary, exits
0). A partial migration is completed in place. ``base/stations/`` is removed
once its probe PNGs are renamed into ``base/sublocations/``.

The project data root is resolved via ``recoil.core.paths.projects_root()`` — no
hardcoded path, no module-level root constant. If the data root is unavailable
the call raises ``ProjectsRootUnresolvable``; the caller turns that into the
``MIGRATION_PENDING`` build-log flag.

Usage:
    python3 recoil/pipeline/tools/migrate_sublocations.py \\
        --project tartarus --location int_lower_decks_maintenance_shaft
"""

from __future__ import annotations

import argparse
import json
import shutil
import sys
from pathlib import Path

# Allow `import recoil...` without an editable install (repo root = 4 up).
sys.path.insert(0, str(Path(__file__).resolve().parent.parent.parent.parent))

from recoil.core.paths import ProjectPaths, projects_root
from recoil.pipeline._lib.sidecar import compute_sha256


# The five probe sublocations, in registry order.
SUBLOCATIONS = ["shaft_lip", "pod_platform", "anchor_cables", "upper_catwalk", "the_drop"]

ADJACENCY = [
    ["shaft_lip", "pod_platform"],
    ["pod_platform", "anchor_cables"],
    ["anchor_cables", "upper_catwalk"],
    ["pod_platform", "the_drop"],
]

DERIVATION = {
    "model": "gpt-image-2",
    "method": "image_edit",
    "prompt_version": "sublocation_ref_v01",
}

# The establishing plate every sublocation ref was image-edited from, relative
# to the location subject dir (``assets/loc/{location}/``).
SOURCE_ASSET = "sheets/sheet_v1.png"


def _write_json(path: Path, payload: dict) -> None:
    path.write_text(json.dumps(payload, indent=2) + "\n")


def migrate(project: str, location: str) -> int:
    root = projects_root()
    paths = ProjectPaths.from_root(root / project)

    base = paths.asset_look_dir("loc", location, "base")
    stations = base / "stations"
    sublocs = base / "sublocations"
    sheet = paths.get_location_sheets_dir(location) / "sheet_v1.png"

    already = sublocs.is_dir() and not stations.exists() and (base / "location.json").is_file()
    if already:
        print(f"[migrate_sublocations] already migrated: {sublocs} (no-op)")
        return 0

    if not sheet.is_file():
        print(
            f"[migrate_sublocations] ERROR: establishing sheet missing: {sheet}",
            file=sys.stderr,
        )
        return 1

    source_sha = compute_sha256(sheet)
    sublocs.mkdir(parents=True, exist_ok=True)

    moved: list[str] = []
    kept: list[str] = []
    registry_entries: dict[str, dict] = {}

    for name in SUBLOCATIONS:
        src = stations / f"station_{name}_v01.png"
        dst = sublocs / f"sublocation_{name}_v01.png"
        if dst.is_file():
            kept.append(name)
        elif src.is_file():
            shutil.move(str(src), str(dst))
            moved.append(name)
        else:
            print(
                f"[migrate_sublocations] ERROR: probe ref missing for {name!r}: {src}",
                file=sys.stderr,
            )
            return 1

        sidecar = {
            "kind": "location_sublocation_ref",
            "sublocation": name,
            "source_asset": SOURCE_ASSET,
            "source_sha256": source_sha,
            "sha256": compute_sha256(dst),
            "derivation": DERIVATION,
        }
        _write_json(dst.parent / (dst.name + ".json"), sidecar)

        registry_entries[name] = {
            "ref": f"sublocations/sublocation_{name}_v01.png",
            "source_sha256": source_sha,
        }

    registry = {
        "schema_version": 1,
        "location_id": location,
        "sublocations": registry_entries,
        "adjacency": ADJACENCY,
    }
    _write_json(base / "location.json", registry)

    if stations.exists():
        leftovers = [q.name for q in stations.iterdir()]
        if leftovers:
            print(
                f"REFUSING to remove {stations}: unexpected leftover files "
                f"{leftovers} — migrate or remove them manually.",
            )
            return 1
        stations.rmdir()

    print(f"[migrate_sublocations] project={project} location={location}")
    print(f"  moved {len(moved)}: {moved}")
    if kept:
        print(f"  already-present {len(kept)}: {kept}")
    print(f"  wrote registry: {base / 'location.json'} ({len(registry_entries)} sublocations)")
    print(f"  removed: {stations}")
    return 0


def main(argv=None) -> int:
    ap = argparse.ArgumentParser(
        description="Migrate a location's station probe refs into the sublocation convention."
    )
    ap.add_argument("--project", required=True)
    ap.add_argument("--location", required=True)
    args = ap.parse_args(argv)
    return migrate(args.project, args.location)


if __name__ == "__main__":
    raise SystemExit(main())
