#!/usr/bin/env python3
"""
nodriver-based probe — the modern Cloudflare-evading browser library.
If this can't mint a route-explorer.com token, no programmatic approach can.
"""
import asyncio, json
import nodriver as uc

BASE = "https://route-explorer.com"

async def main():
    browser = await uc.start(headless=False)  # headed = best chance
    tab = await browser.get(BASE + "/")
    print("loaded homepage")

    # accept cookies
    await tab.evaluate("""
        for (const b of document.querySelectorAll('button')) {
            if (/accept|agree|allow/i.test((b.innerText||'').trim())) b.click();
        }
    """)
    print("accepted cookies (if banner present)")

    cleared = False
    for tick in range(1, 45):
        await asyncio.sleep(1)
        status = await tab.evaluate("""
            (async () => {
                try {
                    const r = await fetch('/api/token', { credentials: 'include' });
                    return r.status;
                } catch (e) { return -1; }
            })()
        """, await_promise=True)
        # also try the page's Retry button
        await tab.evaluate("""
            for (const b of document.querySelectorAll('button')) {
                if (/retry/i.test((b.innerText||'').trim())) b.click();
            }
        """)
        cookies = await browser.cookies.get_all()
        cookie_names = sorted(c.name for c in cookies if "route-explorer" in (c.domain or "") or not c.domain)
        print(f"t+{tick:2d}s /api/token→{status}  cookies={cookie_names}")
        if status == 200:
            cleared = True
            break

    if cleared:
        token_body = await tab.evaluate("""
            (async () => {
                const r = await fetch('/api/token', { credentials: 'include' });
                return await r.text();
            })()
        """, await_promise=True)
        print(f"TOKEN BODY: {token_body[:200]}")
        # try flight-search
        result = await tab.evaluate("""
            (async () => {
                const tk = JSON.parse(await (await fetch('/api/token', {credentials:'include'})).text()).token;
                const r = await fetch('/api/flight-search', {
                    method: 'POST',
                    credentials: 'include',
                    headers: { 'Content-Type': 'application/json', 'X-API-Token': tk },
                    body: JSON.stringify({
                        endpoint: '/route',
                        body: { json: {
                            departureAirportIata: 'DAL',
                            arrivalAirportIata: 'HOU',
                            departureDates: [new Date().toISOString().substring(0,10)],
                            maxStops: 0, limit: 20, includeAppendix: true
                        }}
                    })
                });
                return JSON.stringify({status: r.status, body: (await r.text()).substring(0, 1000)});
            })()
        """, await_promise=True)
        print(f"flight-search → {result}")
    else:
        print("NEVER CLEARED — nodriver also can't pass Turnstile.")

    await asyncio.sleep(2)
    browser.stop()


if __name__ == "__main__":
    uc.loop().run_until_complete(main())
