#!/usr/bin/env python3
"""Import completed 17 Oct comparison outputs fetched read-only into scratch. Never calls live lanes."""
import argparse,concurrent.futures,json,sys,re,hashlib
from pathlib import Path
from types import SimpleNamespace
ROOT=Path(__file__).resolve().parents[1];sys.path.insert(0,str(ROOT/'tools'));sys.path.insert(0,str(ROOT/'lib'))
import ingest_photo_object as imp
p=argparse.ArgumentParser();p.add_argument('scratch');a=p.parse_args();scratch=Path(a.scratch)
# Keep the known ship classes, independent of which model generated their geometry.
import card
classes={cid.split('/')[1]:cid.split('/')[0] for cid in card.load_all(ROOT) if cid.startswith('vehicle.space.') and not any(t in cid for t in ['trellis2-', 'pixal3d-'])}
jobs=[];seen={};existing=card.load_all(ROOT)
for folder,pattern,prefix,model in [('fixed','*.pm.glb','trellis2-fixed-','TRELLIS.2-4B / best of seeds 42,7,1234 / post3d pixel match'),('ab','out-t2-1024-*.glb','trellis2-raw-','TRELLIS.2-4B 1024'),('ab','out-pixal3d-*.glb','pixal3d-ab-','Pixal3D permissive'),('batch','*.glb','pixal3d-batch-','Pixal3D permissive')]:
    for src in sorted((scratch/folder).glob(pattern)):
        stem=src.stem.removesuffix('.pm').removeprefix('out-t2-1024-').removeprefix('out-pixal3d-');photo=(scratch/'fixed'/(stem+'.in.jpg'));thumb=src.with_suffix('.jpg')
        if not thumb.exists():raise ValueError('missing model thumbnail: '+str(thumb))
        digest=hashlib.sha256(src.read_bytes()).hexdigest()
        if digest in seen:
            print('same blob, already covered',src,seen[digest]);continue
        seen[digest]=str(src)
        prov={'method':'picture-to-3D','models':[model],'source':f'prod:/home/forge/adkit-gallery/gpu-3d-{ "trellis-fixed" if folder=="fixed" else "ab" if folder=="ab" else "batch"}-20261017/m/{src.name}', 'source_picture':stem+'.in.jpg','date':'2026-10-17','licence':'generated-original','licence_evidence':'Operator-owned generated original spacecraft references; permissive TRELLIS.2/Pixal3D export lane per 17 Oct licence audit; no third-party source photos','author':model,'scale_evidence':'guessed: native unit treated as one metre; physical spacecraft scale unknown','front_evidence':'guessed: native +Z assumed front; not game-approved'}
        cid=classes.get(stem,'vehicle.space.fighter')+'/'+prefix+stem
        if cid in existing:
            c=card.active(existing[cid]);previous=c['provenance'].get('source_sha256')
            if previous==digest or (not previous and c['provenance'].get('source')==prov['source']):
                c['provenance']['source_sha256']=digest;card.write(ROOT,c);print('unchanged',cid,flush=True);continue
        pf=src.with_suffix('.provenance.json');pf.write_text(json.dumps(prov));cls=classes.get(stem,'vehicle.space.fighter')
        jobs.append(SimpleNamespace(root=str(ROOT),glb=str(src),provenance=str(pf),asset_class=cls,slug=prefix+stem,name=stem.replace('-',' ')+' ('+prefix.rstrip('-')+')',thumbnail=str(thumb),photo=[str(photo)],metres_per_unit=1,yaw=0,no_reuse=False))
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as pool:
    for c in pool.map(imp.ingest,jobs):print(c['id'],c['reuse'],flush=True)
print('unique outputs',len(jobs))
