"""Runs ON gex44. usage: buildings_probe.py <url_root> <out> [styles,csv]: buildings.html per style, every view, a PNG per
view, window.__stats, a phone pass (390 x 844 at 2x) on the village, fatal and console errors, stats.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']
SETTLE_MS = 1500

async def style_types(pg, style):
    return await pg.evaluate(f"fetch('./kits/{style}/style.json').then(r => r.json()).then(j => Object.keys(j.types))")

async def main(root, out, only=''):
    errors, shots, phone = [], {}, {}
    fatal = None
    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]}'))
        pg.on('console', lambda m: m.type == 'error' and errors.append(f'console: {m.text[:300]}'))
        await pg.goto(f'{root}buildings.html')
        try:
            await pg.wait_for_function('window.__ready === true', timeout=120000)
        except Exception as e:
            fatal = str(e)[:200]
        styles = [] if fatal else await pg.evaluate('window.__styles')
        if only:
            styles = [s for s in styles if s in only.split(',')]
        types = {s: await style_types(pg, s) for s in styles}
        for style in styles:
            t0 = types[style][0]
            plan = [(t, 'front') for t in types[style]] + [(t0, v) for v in ('back', 'eaves', 'roof', 'village', 'new')]
            for typ, view in plan:
                name = f'{style}-{view}' if view in ('village', 'new') else f'{style}-{typ}-{view}'
                await pg.evaluate(f"window.__show({json.dumps(view)}, 1, {json.dumps(style)}, {json.dumps(typ)})")
                await pg.wait_for_timeout(SETTLE_MS)
                await pg.screenshot(path=f'{out}/{name}.png')
                shots[name] = await pg.evaluate('window.__stats')
                err = await pg.evaluate('window.__error || null')
                if err:
                    errors.append(f'{name}: {str(err)[:300]}')
        ctx = await b.new_context(viewport={'width': 390, 'height': 844}, device_scale_factor=2)
        mp = await ctx.new_page()
        mp.on('pageerror', lambda e: errors.append(f'phone page: {str(e)[:300]}'))
        mp.on('console', lambda m: m.type == 'error' and errors.append(f'phone console: {m.text[:300]}'))
        await mp.goto(f'{root}buildings.html')
        try:
            await mp.wait_for_function('window.__ready === true', timeout=180000)
        except Exception as e:
            errors.append(f'phone never ready: {str(e)[:120]}'); styles_phone = []
        else:
            styles_phone = styles
        for style in styles_phone:
            await mp.evaluate(f"window.__show('village', 1, {json.dumps(style)}, {json.dumps(types[style][0])})")
            await mp.wait_for_timeout(SETTLE_MS)
            await mp.screenshot(path=f'{out}/phone-{style}-village.png')
            phone[style] = await mp.evaluate('window.__stats')
        await b.close()
    res = {'fatal': fatal, 'styles': styles, 'types': types, 'errors': errors, 'shots': shots, 'phone': phone}
    with open(f'{out}/stats.json', 'w') as f:
        json.dump(res, f, indent=1)
    print(f'styles: {styles}  shots: {len(shots)}  fatal: {fatal}')
    for name, st in shots.items():
        print(f"{name:28s} buildings={st['buildings']} inst={st['instances']} calls={st['drawCalls']} "
              f"tris={st['triangles']} errs={st['errors']} warn={st['warnings']}")
    for style, st in phone.items():
        print(f"phone {style:20s} calls={st['drawCalls']} tris={st['triangles']} viewport=390x844@2x")
    print(f'page errors: {len(errors)}')
    for e in errors:
        print('  ' + e)

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