"""
V8 CDP Leak Probe — dual test runner
Tests the local probe page under two conditions:
  1. Vanilla Playwright (no CDP attachment) — expect CLEAN
  2. Chrome with --remote-debugging-port (CDP attached) — expect LEAK

Hits the local page served at http://127.0.0.1:3457/demo.html
"""
import asyncio
import json
import subprocess
import time
import os
import sys

LOCAL_URL = "http://127.0.0.1:3457/demo.html"
CDP_PORT = 9335
CHROME_BIN = "/usr/bin/google-chrome"
USER_DATA_DIR = "/tmp/v8probe_cdp_test"


async def run_vanilla():
    """Test 1: vanilla Playwright Chromium, no CDP attachment."""
    print("=" * 70)
    print("TEST 1: Vanilla Playwright (no CDP)")
    print("=" * 70)
    from playwright.async_api import async_playwright
    async with async_playwright() as p:
        browser = await p.chromium.launch(
            headless=True,
            args=["--no-sandbox", "--disable-setuid-sandbox", "--disable-dev-shm-usage"]
        )
        ctx = await browser.new_context()
        page = await ctx.new_page()
        await page.goto(LOCAL_URL, wait_until="networkidle", timeout=15000)
        await page.wait_for_timeout(1500)  # let probes settle
        result = await page.evaluate("() => window.__v8Probe || null")
        print(json.dumps(result, indent=2))
        await browser.close()
        return result


async def run_cdp():
    """Test 2: Chrome launched with --remote-debugging-port (CDP attached)."""
    print("=" * 70)
    print("TEST 2: Chrome with --remote-debugging-port (CDP ATTACHED)")
    print("=" * 70)
    # Launch Chrome with CDP enabled
    if os.path.exists(USER_DATA_DIR):
        subprocess.run(["rm", "-rf", USER_DATA_DIR], check=False)
    proc = subprocess.Popen(
        [CHROME_BIN, "--headless=new", "--no-sandbox", "--disable-gpu",
         "--disable-dev-shm-usage", f"--remote-debugging-port={CDP_PORT}",
         f"--user-data-dir={USER_DATA_DIR}", "about:blank"],
        stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
    )
    # Wait for CDP endpoint
    for i in range(20):
        time.sleep(0.5)
        try:
            import urllib.request
            urllib.request.urlopen(f"http://127.0.0.1:{CDP_PORT}/json/version", timeout=1)
            break
        except Exception:
            continue
    else:
        print("CDP endpoint never came up")
        proc.terminate()
        return None

    from playwright.async_api import async_playwright
    async with async_playwright() as p:
        browser = await p.chromium.connect_over_cdp(f"http://127.0.0.1:{CDP_PORT}")
        ctx = browser.contexts[0] if browser.contexts else await browser.new_context()
        page = ctx.pages[0] if ctx.pages else await ctx.new_page()
        await page.goto(LOCAL_URL, wait_until="networkidle", timeout=15000)
        await page.wait_for_timeout(1500)
        result = await page.evaluate("() => window.__v8Probe || null")
        print(json.dumps(result, indent=2))
        await browser.close()
    proc.terminate()
    time.sleep(0.5)
    if proc.poll() is None:
        proc.kill()
    return result


async def main():
    vanilla = await run_vanilla()
    print()
    cdp = await run_cdp()
    print()

    # Verdict
    print("=" * 70)
    print("VERDICT")
    print("=" * 70)
    if not vanilla or not cdp:
        print("FAILED: missing results")
        return

    v_clean = not vanilla.get("isCDP") and not vanilla.get("v8ProtoProxyFired") and not vanilla.get("v8SubclassFired")
    c_leaks = cdp.get("isCDP") and (cdp.get("v8ProtoProxyFired") or cdp.get("v8SubclassFired") or cdp.get("consoleDebugTimingDelta", 0) > 0.15)

    print(f"  Vanilla Playwright (no CDP) → {'CLEAN ✓' if v_clean else 'FALSE POSITIVE ✗'}")
    print(f"    v8ProtoProxyFired: {vanilla.get('v8ProtoProxyFired')}")
    print(f"    v8SubclassFired: {vanilla.get('v8SubclassFired')}")
    print(f"    timingDelta: {vanilla.get('consoleDebugTimingDelta'):.4f}ms")
    print()
    print(f"  Chrome with --remote-debugging-port (CDP) → {'LEAK DETECTED ✓' if c_leaks else 'MISS — V8 probes did NOT fire'}")
    print(f"    v8ProtoProxyFired: {cdp.get('v8ProtoProxyFired')}")
    print(f"    v8SubclassFired: {cdp.get('v8SubclassFired')}")
    print(f"    timingDelta: {cdp.get('consoleDebugTimingDelta'):.4f}ms")

    if v_clean and c_leaks:
        print()
        print("🎯 PROBE WORKS: false on clean, true on CDP. Ship it.")
        return 0
    elif v_clean and not c_leaks:
        print()
        print("⚠️  V8 patches may have closed these too. Check Chrome version.")
        return 1
    else:
        print()
        print("❌ False positive on vanilla — probe too noisy, needs calibration")
        return 2


if __name__ == "__main__":
    sys.exit(asyncio.run(main()))
