"""Runs ON gex44. usage: shots_probe.py <url_root> <out> <shots.json>: each shot {name, page, js[]} loads <page> (reused when
unchanged), waits for window.__ready, runs each js expression (awaited), waits, screenshots <name>.png. Errors in errors.json."""
import asyncio, json, sys
from playwright.async_api import async_playwright
GPU = ['--no-sandbox', '--use-angle=gl-egl', '--use-gl=angle', '--ignore-gpu-blocklist', '--enable-gpu']

async def main(root, out, spec):
    shots, errors, cur = json.load(open(spec)), [], None
    metrics = {}
    async with async_playwright() as p:
        b = await p.chromium.launch(args=GPU)
        pg = await b.new_page(viewport={'width': 1600, 'height': 900})
        pg.on('pageerror', lambda e: errors.append(f'page: {str(e)[:300]}'))
        for s in shots:
            if s['page'] != cur:
                await pg.goto(root + s['page']); cur = s['page']
                await pg.wait_for_function('window.__ready === true || window.__stats', timeout=180000)
            for js in s.get('js', []):
                try: await pg.evaluate(f'(async () => {{ {js} }})()')
                except Exception as e: errors.append(f"{s['name']}: {str(e)[:300]}")
            await pg.wait_for_timeout(s.get('wait', 1500))
            await pg.screenshot(path=f"{out}/{s['name']}.png")
            metrics[s['name']] = await pg.evaluate('({gpu:(()=>{const gl=document.querySelector("#c").getContext("webgl2"),ext=gl.getExtension("WEBGL_debug_renderer_info");return gl.getParameter(ext?ext.UNMASKED_RENDERER_WEBGL:gl.RENDERER)})(),fps:window.__fps,stats:window.__stats,dress:window.__plan()?.dress?.counts, forest:window.__built()?.group.userData.dress?.stats?.()})')
            t = await pg.evaluate('window.__mats ? JSON.stringify(window.__mats) : ""')
            if t: print(s['name'], t[:1500])
        await pg.evaluate("window.__walkStreet();const d=window.__built().group.getObjectByName('dress-driver'),old=d.onBeforeRender;d.onBeforeRender=(r,s,c)=>{if(c?.position)window.__probePosition=[c.position.x,c.position.y,c.position.z];if(r)old(r,s,c)};null;")
        await pg.wait_for_timeout(1000)
        before=await pg.evaluate('window.__probePosition')
        await pg.keyboard.down('w');await pg.wait_for_timeout(800);await pg.keyboard.up('w');await pg.wait_for_timeout(100)
        after=await pg.evaluate('window.__probePosition')
        json.dump({'before':before,'after':after,'moved':sum((a-b)**2 for a,b in zip(after,before))**.5},open(f'{out}/walk.json','w'),indent=1)
        await pg.screenshot(path=f'{out}/walk-input.png')
        await b.close()
    json.dump(metrics, open(f'{out}/metrics.json', 'w'), indent=1)
    json.dump(errors, open(f'{out}/errors.json', 'w'), indent=1)
    print(f'shots: {len(shots)}  errors: {len(errors)}'); [print('  ' + e) for e in errors]

asyncio.run(main(*sys.argv[1:4]))
