#!/usr/bin/env python3
"""
Hawk Hook（Frida）微信冒烟 — 通过 unified /hook/execute 调用，默认 hook_only。

前置：
1. SDK：`cd sdk/app && python3 -m uvicorn main:app --host 0.0.0.0 --port 8899`
2. 手机 Agent 已 WebSocket 上线，Frida 已注入/附着微信（Gadget 或 Root+frida-server）
3. 环境变量 DEVICE_ID（或下面默认值）与真机一致

用法：
  DEVICE_ID=dc9c23e00510 python3 hook_wechat_hwk_smoke.py
  # 发消息（改 TO_ID）
  DEVICE_ID=xxx TO_ID=文件传输助手 CONTENT=hook测试 python3 hook_wechat_hwk_smoke.py --send
"""

from __future__ import annotations

import argparse
import json
import os
import sys
import urllib.error
import urllib.request

BASE = os.environ.get("SDK_BASE", "http://127.0.0.1:8899")
DEVICE_ID = os.environ.get("DEVICE_ID", "dc9c23e00510")


def post(path: str, body: dict, timeout: float = 60.0) -> dict:
    url = f"{BASE.rstrip('/')}{path}"
    data = json.dumps(body).encode("utf-8")
    req = urllib.request.Request(
        url,
        data=data,
        headers={"Content-Type": "application/json"},
        method="POST",
    )
    try:
        with urllib.request.urlopen(req, timeout=timeout) as resp:
            return json.loads(resp.read().decode("utf-8"))
    except urllib.error.HTTPError as e:
        raw = e.read().decode("utf-8", errors="replace")
        try:
            return json.loads(raw)
        except json.JSONDecodeError:
            return {"code": e.code, "error": raw}
    except urllib.error.URLError as e:
        return {"code": 0, "error": str(e.reason)}


def main() -> int:
    p = argparse.ArgumentParser()
    p.add_argument("--send", action="store_true", help="执行 send_message（需 TO_ID/CONTENT）")
    args = p.parse_args()

    steps = [
        ("get_hook_status", {}),
        ("get_wechat_version", {}),
        ("get_process_info", {}),
        ("check_login_state", {}),
        ("get_profile", {}),
        ("get_contacts", {"limit": 5}),
    ]
    if args.send:
        to_id = os.environ.get("TO_ID", "")
        content = os.environ.get("CONTENT", "Hawk Hook 冒烟")
        if not to_id:
            print("请设置 TO_ID（好友备注/昵称或会话标识）", file=sys.stderr)
            return 2
        steps.append(("send_message", {"to_id": to_id, "content": content}))

    print(f"BASE={BASE} DEVICE_ID={DEVICE_ID}\n")
    for action, params in steps:
        body = {
            "device_id": DEVICE_ID,
            "platform": "wechat",
            "action": action,
            "params": params,
            "hook_only": True,
        }
        r = post("/api/v3/hook/execute", body, timeout=120.0)
        ch = r.get("channel_used")
        data = r.get("data")
        ok = False
        if isinstance(data, dict):
            ok = data.get("success", data.get("code") == 200)
        print(f"=== {action} ===")
        print(json.dumps(r, ensure_ascii=False, indent=2)[:4000])
        if not ok and r.get("code") not in (200,):
            print(f"[WARN] {action} 可能未成功，请查 Agent 日志 / Frida 是否附着微信", file=sys.stderr)
        print()
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
