#!/usr/bin/env python3
"""Headless all-club season menu/logo regression, using a read-only SRAM seed.

Usage: verify_season_teams.py current.bin /private/output --seed copy.srm
Seed is a valid 16KB Genesis Plus GX save with default One-player preferences.
Only generated case saves are written. No window or running emulator is touched.
"""
from pathlib import Path
import argparse
import json
import os
import struct
import subprocess
from concurrent.futures import ThreadPoolExecutor


def main():
    ap = argparse.ArgumentParser(description=__doc__)
    ap.add_argument('rom', type=Path)
    ap.add_argument('work_dir', type=Path)
    ap.add_argument('--seed', type=Path, required=True)
    args = ap.parse_args()
    here = Path(__file__).resolve().parent
    seed = args.seed.read_bytes()
    assert len(seed) == 16384
    work = args.work_dir.resolve()
    work.mkdir(parents=True, exist_ok=True)

    def run_case(item):
        mode, coop = item
        case = work/f'mode{mode}-p{2 if coop else 1}'
        case.mkdir(exist_ok=True)
        raw = bytearray(seed)
        b = bytearray(raw[1::2])
        b[0x1000:0x1220] = bytes(0x220)
        b[0x1000:0x1004] = b'SESN'
        struct.pack_into('>6H', b, 0x1004, 0, 0, 0, {1:84, 2:31, 3:7}[mode], mode, 3)
        # Round10 has offset31: Left from the user's club hit the old opponent,
        # reproducing identical logos in the old build before late forcing ran.
        struct.pack_into('>HIHHHH', b, 0x1212, 0x5343, 0, 0, 0, 10, mode)
        b[0x1fff] = sum(b[:0x1ffe]) % 256
        b[0x1ffe] = b[0x1fff] ^ 255
        raw[1::2] = b
        save = case/'battery.srm'
        save.write_bytes(raw)
        lines = ['1000 snap', '1100 press 1 Down 5']
        checks = [dict(frame=1000, action='initial')]
        if coop:
            lines += ['1200 press 1 Right 5']
            checks += [dict(frame=1270, action='players')]
        lines += ['1300 press 1 Down 5']
        t = 1500
        for step in range(1,33):
            lines += [f'{t} press 1 Left 5']
            checks += [dict(frame=t+70, action='team', step=step)]
            if step == 20:
                lines += [f'{t+70} snap']
            t += 100
        lines += [f'{t} press 1 Down 5']
        t += 150
        for direction in ['Right', 'Left']:
            for _ in range(32):
                lines += [f'{t} press 1 {direction} 5']
                checks += [dict(frame=t+70, action='opponent')]
                t += 100
        lines += [f'{t} press 1 Start 5', f'{t+400} press 1 Down 5', f'{t+500} press 1 C 5']
        checks += [dict(frame=t+300, action='pregame'), dict(frame=t+900, action='simulated')]
        lines += [f'{t+1100} press 1 Start 5', f'{t+1450} press 1 Down 5']
        for k, direction in enumerate(['Right', 'Left']):
            frame = t+1600+200*k
            lines += [f'{frame} press 1 {direction} 5']
            checks += [dict(frame=frame+100, action='continued-players')]
        lines += [f'{t+2100} press 1 Down 5', f'{t+2250} press 1 Left 5']
        checks += [dict(frame=t+2350, action='continued-team-locked')]
        lines += [f'{t+2450} snap', f'{t+2500} exit']
        cmd = case/'commands.txt'
        cmd.write_text('\n'.join(lines)+'\n')
        (case/'checks.json').write_text(json.dumps(checks, indent=2)+'\n')
        env = dict(os.environ, GPGX_DEV='513', GPGX_SRM=str(save),
                   GPGX_HOOK=str(here/'testcases/season_teams_hook.py'), SEASON_MODE=str(mode))
        with (case/'log.txt').open('w') as log:
            subprocess.run(['nice','-n','19','python3',str(here/'test_core.py'),str(args.rom.resolve()),str(cmd),str(case)], env=env, check=True, stdout=log, stderr=log)
        result = json.loads((case/'results.json').read_text())
        assert len(result) == len(checks), (mode, coop, len(result), len(checks))
        return dict(mode=mode, players='teammates' if coop else 'one', checked_screens=len(result))

    with ThreadPoolExecutor(max_workers=3) as pool:
        reports = list(pool.map(run_case, [(m,c) for m in [1,2,3] for c in [False,True]]))
    (work/'results.json').write_text(json.dumps(reports, indent=2)+'\n')
    print('PASS all32 clubs, both opponent directions, One/Teammates, Full/Light/Mini, first simulated round and continued odd-round toggles')


if __name__ == '__main__':
    main()
