#!/usr/bin/env python3
"""CDP E2E Test v2: 使用真实JWT Token进行前端端到端测试"""
import json, time, base64, urllib.request

REAL_TOKEN = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODE5Njg1MDAsImlhdCI6MTc3OTM3NjUwMCwidXNlcl9pZCI6ImFkbWluIn0.dHdo1NciPDC8-yR0P-CHv2x0hsh3-G2sHOr9E8VBvws'

print('=== CDP E2E Test v2 ===')

# Open page
req = urllib.request.Request('http://127.0.0.1:9225/json/new?url=http://localhost:5199/', method='PUT')
resp = urllib.request.urlopen(req, timeout=10)
page = json.loads(resp.read())
ws_url = page['webSocketDebuggerUrl']
page_id = page['id']
print(f'Page: {page_id}')

from websocket import create_connection
ws = create_connection(ws_url, timeout=10)

def cdp(method, params=None, msg_id=1):
    ws.send(json.dumps({'id': msg_id, 'method': method, 'params': params or {}}))

def recv_all(timeout=3):
    ws.settimeout(timeout)
    msgs = []
    try:
        while True:
            msgs.append(ws.recv())
    except:
        pass
    return msgs

def find_result(msgs, msg_id):
    for m in msgs:
        try:
            d = json.loads(m)
            if d.get('id') == msg_id:
                return d.get('result', {})
        except:
            pass
    return None

# Enable domains
cdp('Page.enable', {}, 1)
cdp('Runtime.enable', {}, 2)
cdp('Network.enable', {}, 3)
cdp('Log.enable', {}, 4)
recv_all(1)

# Inject real token
print('\n--- Inject Token ---')
cdp('Runtime.evaluate', {
    'expression': 'localStorage.setItem("token", "%s"); localStorage.setItem("user_id", "admin"); "OK"' % REAL_TOKEN,
    'returnByValue': True
}, 50)
recv_all(2)

# Reload
print('\n--- Reload Page ---')
cdp('Page.navigate', {'url': 'http://localhost:5199/'}, 60)
time.sleep(4)
all_msgs = recv_all(5)

# Analyze
print('\n--- Console Analysis ---')
errors = []
for m in all_msgs:
    try:
        d = json.loads(m)
    except:
        continue
    method = d.get('method', '')
    params = d.get('params', {})
    
    if method == 'Log.entryAdded':
        entry = params.get('entry', {})
        lvl = entry.get('level', 'log')
        text = str(entry.get('text', ''))[:200]
        if lvl == 'error':
            errors.append(text)
        print(f'  [{lvl}] {text}')
    
    elif method == 'Runtime.consoleAPICalled':
        args = params.get('args', [])
        lvl = params.get('type', 'log')
        texts = [str(a.get('value', '') or a.get('description', ''))[:150] for a in args]
        combined = ' '.join(texts)
        if lvl == 'error':
            errors.append(combined)
        print(f'  [{lvl}] {combined}')
    
    elif method == 'Runtime.exceptionThrown':
        exc = params.get('exceptionDetails', {})
        text = exc.get('text', '')
        errors.append(text)
        print(f'  [EXCEPTION] {text}')

# Network
print('\n--- Network API Calls ---')
for m in all_msgs:
    try:
        d = json.loads(m)
    except:
        continue
    method = d.get('method', '')
    params = d.get('params', {})
    if method == 'Network.responseReceived':
        resp = params.get('response', {})
        url = resp.get('url', '')
        status = resp.get('status', 0)
        if '/api/' in url:
            print(f'  [{status}] {url[-80:]}')
    elif method == 'Network.loadingFailed':
        print(f'  [FAIL] {params.get("errorText","?")}')

# Runtime checks
print('\n--- Runtime State ---')
checks = [
    'localStorage.getItem("token") ? "TOKEN_OK:" + localStorage.getItem("token").slice(0,20) + "..." : "NO_TOKEN"',
    'localStorage.getItem("user_id") || "none"',
    'document.title',
    'document.querySelectorAll("[class*=\\"message\\"]").length + " message elements"',
    '(function(){try{var s=document.querySelector("#root");return s?s.children.length+" root children":"no root"}catch(e){return e.message}})()',
]
for idx, expr in enumerate(checks):
    cdp('Runtime.evaluate', {'expression': expr, 'returnByValue': True}, 200 + idx)
    recv_msgs = recv_all(2)
    r = find_result(recv_msgs, 200 + idx)
    if r:
        val = r.get('result', {}).get('value', '?')
        print(f'  {val}')

# Screenshot
print('\n--- Screenshot ---')
cdp('Page.captureScreenshot', {'format': 'png'}, 300)
recv_msgs = recv_all(5)
r = find_result(recv_msgs, 300)
if r and r.get('data'):
    img = base64.b64decode(r['data'])
    with open('/tmp/cyrene_e2e_v2.png', 'wb') as f:
        f.write(img)
    print(f'  Saved: {len(img)} bytes')

if errors:
    print(f'\n=== {len(errors)} ERRORS ===')
    for e in errors:
        print(f'  - {e[:200]}')
else:
    print('\n=== ZERO ERRORS ===')

ws.close()
print('[DONE]')
