# -*- coding: utf-8 -*-
"""
百家号 - 使用 CDP Input 模拟键盘输入
"""
import sys, socket, json, time, urllib.request, base64, os, glob, random
sys.stdout.reconfigure(encoding='utf-8')

HOST = 'localhost'
PORT = 9223

TITLE = '山东医学院更名对比'
PARAGRAPHS = [('normal', '正文测试。')]

def rand_sleep(s, t):
    time.sleep(random.uniform(s, t))

def ws_connect_cdp(sock):
    """CDP WebSocket"""
    def recv(sock):
        def rx(n):
            b = b''
            while len(b) < n:
                b += sock.recv(n - len(b))
            return b
        h = rx(2)
        n = h[1] & 0x7f
        if n == 126:
            n = int.from_bytes(rx(2), 'big')
        elif n == 127:
            n = int.from_bytes(rx(8), 'big')
        return rx(n).decode('utf-8')

    def send(s, d):
        data = json.dumps(d).encode('utf-8')
        n = len(data)
        m = b'\x01\x02\x03\x04'
        if n <= 125:
            hdr = bytes([0x81, n | 0x80]) + m
        elif n <= 65535:
            hdr = bytes([0x81, 0xFE]) + n.to_bytes(2, 'big') + m
        s.send(hdr + bytes(data[i] ^ m[i % 4] for i in range(n)))

    return send, recv, sock

# 通过 HTTP CDP 执行
import urllib.request

pages = json.loads(urllib.request.urlopen(f'http://{HOST}:{PORT}/json').read())
page_id = [p['id'] for p in pages if 'baijiahao.baidu.com' in p['url']][0]
print(f"[OK] Page ID: {page_id}")

# 创建 CDP WebSocket 连接
from urllib.parse import urlparse
import urllib.parse

ws_url = f'ws://{HOST}:{PORT}/devtools/page/{page_id}'
parsed = urlparse(ws_url)
sock = socket.create_connection((parsed.hostname, parsed.port or 80), timeout=15)
key = 'dGhlIHNhbXBsZSBub25jZQ=='
handshake = f"GET {parsed.path} HTTP/1.1\r\nHost:{parsed.hostname}:{parsed.port}\r\nUpgrade:websocket\r\nConnection:Upgrade\r\nSec-WebSocket-Key:{key}\r\nSec-WebSocket-Version:13\r\n\r\n"
sock.send(handshake.encode())
resp = b''
while b'\r\n\r\n' not in resp:
    resp += sock.recv(4096)

def send(s, d):
    data = json.dumps(d).encode('utf-8')
    n = len(data)
    m = b'\x01\x02\x03\x04'
    if n <= 125:
        hdr = bytes([0x81, n | 0x80]) + m
    elif n <= 65535:
        hdr = bytes([0x81, 0xFE]) + n.to_bytes(2, 'big') + m
    s.send(hdr + bytes(data[i] ^ m[i % 4] for i in range(n)))

def recv(s):
    h = s.recv(2)
    n = h[1] & 0x7f
    if n == 126:
        n = int.from_bytes(s.recv(2), 'big')
    elif n == 127:
        n = int.from_bytes(s.recv(8), 'big')
    return s.recv(n).decode('utf-8')

# ============================================
# 方法1: 尝试点击标题框获取焦点，然后用 CDP Input
# ============================================
print("\n[Step 1] 点击标题框...")

mid = 1

# 点击 input-box
send(sock, {'id': mid, 'method': 'Runtime.evaluate', 'params': {'expression': """
(function(){
    var inputBox = document.querySelector('.input-box');
    if(inputBox) {
        inputBox.click();
        return 'clicked';
    }
    return 'not_found';
})()
"""}})
r = recv(sock)
print(f"  [click] {json.loads(r)['result']['result']['value']}")
rand_sleep(1, 2)

# ============================================
# 方法2: 使用 Input.dispatchKeyEvent 模拟 Ctrl+A 删除
# ============================================
print("\n[Step 2] 模拟全选删除...")

mid += 1
send(sock, {'id': mid, 'method': 'Input.dispatchKeyEvent', 'params': {'type': 'keyDown', 'key': 'a', 'modifiers': ['Control']}})
recv(sock)

mid += 1
send(sock, {'id': mid, 'method': 'Input.dispatchKeyEvent', 'params': {'type': 'keyDown', 'key': 'Delete'}})
recv(sock)

rand_sleep(0.5, 1)

# ============================================
# 方法3: 逐字符输入
# ============================================
print("\n[Step 3] 逐字符输入标题...")

for char in TITLE:
    mid += 1
    send(sock, {'id': mid, 'method': 'Input.dispatchKeyEvent', 'params': {'type': 'keyDown', 'key': char, 'text': char}})
    recv(sock)
    rand_sleep(0.1, 0.2)

rand_sleep(1, 2)

# 验证
mid += 1
send(sock, {'id': mid, 'method': 'Runtime.evaluate', 'params': {'expression': """
(function(){
    var inputBox = document.querySelector('.input-box');
    if(inputBox){
        return 'title=' + (inputBox.innerText||'').trim().substring(0,40);
    }
    return 'no_input_box';
})()
"""}})
r = recv(sock)
print(f"  [verify] {json.loads(r)['result']['result']['value']}")

sock.close()
print("\n[DONE]")