#!/usr/bin/env python3
"""The real partial native SRAM write must not be accepted as a saved game.

Loads the captured matching-checksum/unfinished-write state of match2385.
Runs the actual release observer with an observation-only validate callback;
the callback asserts readiness before any other statistical validation can run.
No emulated memory, gameplay values or native RNG are written.
"""
from pathlib import Path
import argparse, hashlib, json, os, shutil, subprocess

ap = argparse.ArgumentParser(description=__doc__)
ap.add_argument('rom', type=Path)
ap.add_argument('output', type=Path)
ap.add_argument('--state', type=Path, required=True)
ap.add_argument('--seed', type=Path, required=True)
ap.add_argument('--observer', type=Path)
a = ap.parse_args()
h = Path(__file__).resolve().parent
o = a.output.resolve()
o.mkdir(parents=True, exist_ok=True)
observer = (a.observer or h/'testcases/full_cpu_hook.py').resolve()
shutil.copyfile(a.seed, o/'battery.srm')
(o/'commands.txt').write_text(f'1 load {a.state.resolve()}\n9 exit\n')
(o/'hook.py').write_text('''from pathlib import Path
import os,json,struct
p=Path(outdir)
exec(compile(Path(os.environ['READINESS_OBSERVER']).read_text(),os.environ['READINESS_OBSERVER'],'exec'),globals())
calls=[];observations=[];current_frame=0
def validate(b):
 assert current_frame>=3,('observer accepted checksum before complete stable SRAM',current_frame)
 assert all(int.from_bytes(b[0x1010+16*t:0x1012+16*t],'big')==1 for t in range(32))
 calls.append(current_frame)
 return struct.unpack_from('>6H',b,0x1004)
def test_tick(f):
 global current_frame
 current_frame=f;b=battery();gp=[int.from_bytes(b[0x1010+16*t:0x1012+16*t],'big') for t in range(32)]
 assert [rw(0xc6da),rw(0xca3e)]==[1,2],('native result changed',f)
 if f==1:
  assert b[0x1fff]==sum(b[:0x1ffe])%256 and b[0x1ffe]==(b[0x1fff]^255),'fixture no longer reproduces matching checksum'
  assert gp[:26]==[1]*26 and gp[26:]==[0]*6,('partial native write fixture',gp)
 verify_tick(f)
 observations.append(dict(frame=f,all32_GP_complete=all(x==1 for x in gp),accepted=list(calls)))
 if f==8:
  assert calls==[3],('expected one acceptance after complete record is stable for two observations',calls)
  (p/'observations.json').write_text(json.dumps(observations,indent=2)+'\\n')
''')
env = {k:v for k,v in os.environ.items() if not k.startswith('GPGX_')}
env.update(GPGX_HOOK=str(o/'hook.py'), GPGX_SRM=str(o/'battery.srm'), CASE_DIR=str(o), READINESS_OBSERVER=str(observer))
with (o/'log.txt').open('w') as log:
    subprocess.run(['python3', str(h/'test_core.py'), str(a.rom.resolve()), str(o/'commands.txt'), str(o)], env=env, stdout=log, stderr=log, check=True, timeout=30)
sha = lambda p: hashlib.sha256(p.read_bytes()).hexdigest()
(o/'results.json').write_text(json.dumps(dict(rom_sha256=sha(a.rom), observer_sha256=sha(observer), state_sha256=sha(a.state), seed_sha256=sha(a.seed), native_checksum_collision_reproduced=True, complete_stable_record_accepted_once=True, unchanged_native_score=[1,2]), indent=2)+'\n')
print('PASS real native partial-write checksum collision rejected; all32 records complete and stable before acceptance')
