#!/usr/bin/env python3
"""Apply corrections.json exported from review.html.

    python3 apply_corrections.py ~/Downloads/corrections.json [--dry-run]

Moves each crop to the folder you chose. "discard" goes to labelling/<clip>/discard/,
which the sweep ignores — nothing is deleted, so a misclick is recoverable.

Refuses to move a file it cannot find exactly once, rather than guessing: a
half-applied correction set would put a crop in two folders and quietly
duplicate a label.
"""
import sys, json, glob, os, shutil

if len(sys.argv) < 2:
    sys.exit(__doc__)
path = sys.argv[1]
DRY = "--dry-run" in sys.argv
corr = json.load(open(path))
if not corr:
    sys.exit("no corrections in that file")

moved = skipped = 0
for fname, c in corr.items():
    clip, to = c["clip"], c["to"]
    hits = glob.glob(f"labelling/{clip}/**/{fname}", recursive=True)
    if len(hits) != 1:
        print(f"[skip] {fname}: found {len(hits)} copies, expected 1")
        skipped += 1
        continue
    src = hits[0]
    dst_dir = f"labelling/{clip}/{to}"
    dst = f"{dst_dir}/{fname}"
    if os.path.abspath(src) == os.path.abspath(dst):
        continue
    print(f"{'would move' if DRY else 'move'} {c['from']} -> {to}: {fname}")
    if not DRY:
        os.makedirs(dst_dir, exist_ok=True)
        shutil.move(src, dst)
    moved += 1

print(f"\n{moved} moved, {skipped} skipped{' (dry run)' if DRY else ''}")
if not DRY and moved:
    print("re-run verify_labels.py to confirm the set is still consistent")
