"""Write the NEXT card version of every spacecraft whose gun or hinge axes point the wrong way (tools/space/axes_space.py),
17 Oct 2026, before the cloud publish: card versions are immutable, the GLB and the painted copy stay the same.
usage: python3 tools/space/fix_axes.py [--dry-run]"""
import json, os, sys
ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.path.insert(0, os.path.join(ROOT, 'lib')); sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import card as cardlib  # noqa: E402
from axes_space import measured_axes  # noqa: E402

dry = '--dry-run' in sys.argv
changed = 0
for cid, versions in sorted(cardlib.load_all(ROOT).items()):
    if not cid.startswith('vehicle.space.'):
        continue
    c = json.loads(json.dumps(versions[-1]))
    moving = (c.get('nodes') or {}).get('moving') or {}
    if not moving:
        continue
    glb_path = f"{ROOT}/store/blobs/{c['files']['glb'].split(':')[1]}.glb"
    new = measured_axes(glb_path, moving)
    diff = {n: ax for n, (ax, _) in new.items() if ax and [round(x, 3) for x in ax] != [round(x, 3) for x in moving[n]['axis']]}
    if not diff:
        continue
    changed += 1
    kinds = {}
    for n, ax in diff.items():
        moving[n]['axis'] = list(ax); moving[n]['axis_source'] = 'measured'
        c['nodes']['axes'][n] = list(ax); kinds[moving[n]['kind']] = kinds.get(moving[n]['kind'], 0) + 1
    print(f"{cid}: {len(diff)} axes fixed {kinds}")
    if dry:
        continue
    c['version'] = max(v['version'] for v in versions) + 1
    c['release'] = cardlib.release_hash(c)
    print('  ->', cardlib.write(ROOT, c))
print(changed, 'cards', '(dry run)' if dry else 'written')
