#!/usr/bin/env python3
"""Mandatory exact-source main-menu regression; never installs or closes RetroArch."""
from pathlib import Path
from datetime import datetime,timezone
import argparse,hashlib,json,subprocess,sys
from main_menu_scope import normalize,PARENT,sites
ap=argparse.ArgumentParser();ap.add_argument('rom',type=Path);ap.add_argument('output',type=Path);a=ap.parse_args();rom=a.rom.resolve();o=a.output.resolve();o.mkdir(parents=True,exist_ok=True);h=Path(__file__).resolve().parent;sha=lambda p:hashlib.sha256(p.read_bytes()).hexdigest();b=rom.read_bytes();normalize(b)
negatives=[]
for name,at in [('physics',0xb810),('goalie-Y',0x2fe040),('market',0x239500),('season',0x2f8000),('ordinary-uniform',0x260100),('Allstar-uniform',0x22d200),('startup-art',0x2a1000),('audio-outside-main',0x1a50a),('CRC-table',0x25c800),('extra-credits-pixel',0x2d0060),('outside-hook',0x17c61),('new-Y-module',0x25cc40),('new-OVR-module',0x25ce20)]:
 bad=bytearray(b);bad[at]^=1
 try:normalize(bad)
 except AssertionError as e:negatives.append(dict(name=name,address=hex(at),rejected=str(e)))
 else:raise AssertionError(('main-menu scope mutation escaped',name))
report=dict(status='running',ROM_sha256=sha(rom),started=datetime.now(timezone.utc).isoformat(),parent_sha256=PARENT,scope_guarded_sites=len(sites()),scope_negatives=negatives,checks=[])
def save():(o/'results.json').write_text(json.dumps(report,indent=2)+'\n')
save()
for label,script,flags in [('loop-reader-ABI','main_menu_abi',[]),('active-core','main_menu_active',['--section','core']),('active-records','main_menu_active',['--section','records']),('active-journal','main_menu_active',['--section','journal']),('continuous-audio-input','main_menu_continuous',[])]:
 cmd=[sys.executable,str(h/'testcases'/(script+'.py')),str(rom),str(o/label),*flags]
 with(o/(label+'.log')).open('w')as f:r=subprocess.run(cmd,stdout=f,stderr=f,timeout=3600)
 report['checks'].append(dict(name=label,returncode=r.returncode,source_sha256=sha(h/'testcases'/(script+'.py')),command=cmd));save();print(label,'PASS'if r.returncode==0 else'FAIL',flush=True)
 if r.returncode:report['status']='failed';save();raise SystemExit('Main-menu release blocked: '+label)
assert sha(rom)==report['ROM_sha256'];report.update(status='passed',finished=datetime.now(timezone.utc).isoformat());save();print('PASS all mandatory main-menu scope, complete active CRC/validation/journal, native ABI, real input/audio and negatives; opened screenshots and physical pads remain separate',flush=True)
