"""Record the same real-app discovery failures on either checkout.
Usage: python drive.py ORIGIN PAIRING_PATH_FILE OUTPUT_DIRECTORY SESSION
Run fixtures.py first. Supply a fresh app home for each side.
"""
import hashlib, json, pathlib, subprocess, sys, time
origin, pairing_file, output, session = sys.argv[1:]
out = pathlib.Path(output) / time.strftime('%Y%m%d-%H%M%S')
out.mkdir(parents=True)
cli = ['npx', '--yes', 'agent-browser', '--session', session]
def browser(*args, private=False):
    result = subprocess.run(cli + list(args), capture_output=True, text=True)
    if result.returncode:
        raise RuntimeError(result.stderr if private else result.stdout + result.stderr)
    if not private:
        with (out / 'driver.log').open('a') as log:
            log.write(' '.join(args) + '\n' + result.stdout + '\n')
    return result.stdout
browser('set', 'viewport', '1280', '800')
browser('open', origin + pathlib.Path(pairing_file).read_text().strip(), private=True)
browser('wait', '--fn', "!!document.querySelector('main[aria-label=Welcome]') || !!Array.from(document.querySelectorAll('button')).find(b=>b.getAttribute('aria-label')==='Settings')")
if 'Welcome to T3 Code' in browser('get', 'text', 'body'):
    browser('find', 'role', 'button', 'click', '--name', 'Start', '--exact')
browser('open', origin + '/settings/labs')
browser('wait', '--text', 'Linked environments')
if 'false' in browser('get', 'attr', '[role=switch][aria-label="Linked environments"]', 'aria-checked'):
    browser('click', '[role=switch][aria-label="Linked environments"]')
browser('open', origin + '/settings/connections')
browser('wait', '--text', 'No linked environments')
browser('record', 'start', str(out / 'link-discovery.webm'))
browser('find', 'role', 'button', 'click', '--name', 'Link', '--exact')
cases = [
    ('refused-connection', 'http://127.0.0.1:18741'),
    ('dns-failure', 'https://discovery-proof-does-not-exist.ts.net'),
    ('incompatible-response', 'http://127.0.0.1:18742'),
    ('timeout', 'http://127.0.0.1:18743'),
]
observations = []
try:
    for label, address in cases:
        browser('find', 'label', 'Address', 'fill', address, '--exact')
        browser('find', 'label', 'Pairing code', 'fill', 'synthetic-proof-code', '--exact')
        browser('click', '[role=dialog] button[type=submit]')
        browser('wait', '--text', 'Could not link the environment')
        browser('hover', '[data-slot=toast-viewport]')
        # Accept a still only after two screenshots 500 ms apart match byte for byte.
        stable = False
        for attempt in range(10):
            first = out / (label + '-stability-a.png')
            second = out / (label + '-stability-b.png')
            browser('screenshot', str(first))
            time.sleep(.5)
            browser('screenshot', str(second))
            if first.read_bytes() == second.read_bytes():
                (out / (label + '.png')).write_bytes(second.read_bytes())
                stable = True
                break
        if not stable:
            raise RuntimeError('The capture did not stabilize: ' + label)
        text = browser('get', 'text', 'body')
        observations.append({'label': label, 'address': address, 'visibleText': text, 'stable': stable})
        if browser('get', 'count', '[aria-label="Dismiss notification"]').strip() != '0':
            browser('click', '[aria-label="Dismiss notification"]')
    browser('find', 'role', 'button', 'click', '--name', 'Cancel', '--exact')
finally:
    browser('record', 'stop')
    (out / 'observations.json').write_text(json.dumps(observations, indent=2))
print(out)
