#!/usr/bin/env bash
# 微信全量验收：等 ADB → oneclick → 采集 Hook 数据 → REST 矩阵 → Hook catalog → 汇总报告
set -euo pipefail
SDK_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
SCRIPTS="${SDK_ROOT}/scripts"
OUT_DIR="${SDK_ROOT}/tmp"
DOC_DIR="$(cd "${SDK_ROOT}/.." && pwd)/开发文档/5、接口/06-验收与矩阵"
TS="$(date +%Y%m%d_%H%M%S)"
REPORT_JSON="${OUT_DIR}/wechat_full_acceptance_${TS}.json"
REPORT_MD="${DOC_DIR}/2026-05-24_微信全量验收报告_${TS}.md"
LOG="${OUT_DIR}/wechat_full_acceptance_${TS}.log"

DEVICE_SERIAL="${DEVICE_SERIAL:-}"
ADB_WAIT_SEC="${ADB_WAIT_SEC:-600}"
SDK_PORT="${SDK_PORT:-8899}"
SDK_BASE="http://127.0.0.1:${SDK_PORT}"

exec > >(tee -a "${LOG}") 2>&1
echo "=== 微信全量验收 ${TS} ==="

# ── 1. 等待任意 ADB 设备（无线 IP 或 USB serial）──
if [[ -z "${DEVICE_SERIAL}" ]]; then
  for candidate in "192.168.110.80:5555" "192.168.1.126:5555"; do
    if bash "${SCRIPTS}/wait_adb_device.sh" "${candidate}" 30 2; then
      DEVICE_SERIAL="${candidate}"
      break
    fi
  done
fi
if [[ -z "${DEVICE_SERIAL}" ]]; then
  echo "轮询任意 USB/ADB 设备 (${ADB_WAIT_SEC}s)..."
  deadline=$((SECONDS + ADB_WAIT_SEC))
  while (( SECONDS < deadline )); do
    DEVICE_SERIAL="$(adb devices | awk '/\tdevice$/{print $1; exit}')"
    if [[ -n "${DEVICE_SERIAL}" ]]; then
      echo "adb_ready ${DEVICE_SERIAL}"
      break
    fi
    sleep 3
  done
fi
[[ -n "${DEVICE_SERIAL}" ]] || { echo "FATAL: 无 ADB 设备"; exit 2; }

export DEVICE_SERIAL
echo "设备: ${DEVICE_SERIAL}"

# ── 2. oneclick（WS + Frida）──
pkill -f "agent.py -d ${DEVICE_SERIAL}" 2>/dev/null || true
bash "${SCRIPTS}/frida_workphone_oneclick.sh" || { echo "oneclick 失败"; exit 3; }

# 等 WS + RPC
for _i in $(seq 1 40); do
  ws="$(curl -s "${SDK_BASE}/api/v3/connection/status" | python3 -c "import sys,json;print(json.load(sys.stdin)['data']['online_ws_count'])" 2>/dev/null || echo 0)"
  rpc="$(grep -c 'RPC ping: pong' "${SDK_ROOT}/logs/agent.log" 2>/dev/null || echo 0)"
  if [[ "${ws}" -ge 1 && "${rpc}" -ge 1 ]]; then
    echo "WS+Frida 就绪 ws=${ws}"
    break
  fi
  sleep 2
done

DEV="${DEVICE_SERIAL}"
export SDK_MATRIX_VERIFY=1 WECHAT_WS_HOOK_ONLY=1 WECHAT_BACKEND_ONLY=1
export SDK_BASE_URL="${SDK_BASE}" SDK_DEVICE_ID="${DEV}" SDK_E2E_TO_ID=filehelper

# ── 3. 连接 / 探测 / Hook 数据 ──
mkdir -p "${OUT_DIR}"
curl -s "${SDK_BASE}/api/v3/connection/status" > "${OUT_DIR}/acceptance_connection_${TS}.json"
curl -s "${SDK_BASE}/api/v3/hook/probe/${DEV}" > "${OUT_DIR}/acceptance_hook_probe_${TS}.json"
curl -s "${SDK_BASE}/api/v3/hook/data/${DEV}?modules=profile,contacts,groups,messages,labels,moments,device_info,wechat_version,hook_status,process_info,storage_info,network_info,login_state,favorites" \
  > "${OUT_DIR}/acceptance_hook_data_${TS}.json"

curl -s --max-time 30 -X POST "${SDK_BASE}/api/v3/hook/execute" \
  -H "Content-Type: application/json" \
  -d "{\"device_id\":\"${DEV}\",\"platform\":\"wechat\",\"action\":\"ping\",\"params\":{},\"hook_only\":true}" \
  > "${OUT_DIR}/acceptance_ping_${TS}.json"

curl -s --max-time 45 -X POST "${SDK_BASE}/api/v3/message/send" \
  -H "Content-Type: application/json" \
  -d "{\"device_id\":\"${DEV}\",\"platform\":\"wechat\",\"to_id\":\"filehelper\",\"content\":\"[全量验收 ${TS}]\",\"msg_type\":\"text\"}" \
  > "${OUT_DIR}/acceptance_send_${TS}.json"

# ── 4. REST 矩阵 + Hook catalog ──
cd "$(cd "${SDK_ROOT}/.." && pwd)"
python3 sdk/tests/test_wechat_full_e2e.py --matrix 2>&1 | tee "${OUT_DIR}/acceptance_e2e_${TS}.log"
E2E_JSON="$(ls -t sdk/tmp/matrix_v8056_verify_${DEV//:/_}_*.json 2>/dev/null | head -1 || ls -t sdk/tmp/matrix_v8056_verify_*.json 2>/dev/null | head -1 || true)"

python3 sdk/scripts/matrix_hook_catalog_verify.py -d "${DEV}" 2>&1 | tee "${OUT_DIR}/acceptance_catalog_${TS}.log"
CAT_JSON="$(ls -t sdk/tmp/matrix_hook_catalog_${DEV//:/_}_*.json 2>/dev/null | head -1 || ls -t sdk/tmp/matrix_hook_catalog_*.json 2>/dev/null | head -1 || true)"

# ── 5. 汇总 JSON + MD ──
python3 <<PY
import json, os, glob
from datetime import datetime
from pathlib import Path

ts = "${TS}"
dev = "${DEV}"
out = Path("${REPORT_JSON}")
doc = Path("${REPORT_MD}")
tmp = Path("${OUT_DIR}")

def load(p):
    try:
        return json.loads(Path(p).read_text())
    except Exception:
        return {}

e2e_path = "${E2E_JSON}" or ""
cat_path = "${CAT_JSON}" or ""
e2e = load(e2e_path) if e2e_path else {}
cat = load(cat_path) if cat_path else {}

summary = {
    "timestamp": datetime.now().isoformat(),
    "device_id": dev,
    "connection": load(tmp / f"acceptance_connection_{ts}.json"),
    "hook_probe": load(tmp / f"acceptance_hook_probe_{ts}.json"),
    "hook_data": load(tmp / f"acceptance_hook_data_{ts}.json"),
    "ping": load(tmp / f"acceptance_ping_{ts}.json"),
    "send_message": load(tmp / f"acceptance_send_{ts}.json"),
    "e2e_matrix": {"path": e2e_path, "passed": e2e.get("passed"), "total": e2e.get("total"), "success_rate": e2e.get("success_rate")},
    "hook_catalog": {"path": cat_path, "passed": cat.get("passed"), "total": cat.get("total"), "success_rate": cat.get("success_rate")},
}
out.write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")

e2e_p, e2e_t = summary["e2e_matrix"].get("passed"), summary["e2e_matrix"].get("total")
cat_p, cat_t = summary["hook_catalog"].get("passed"), summary["hook_catalog"].get("total")
probe = summary["hook_probe"].get("data") or summary["hook_probe"]
supports = probe.get("supports_hook") if isinstance(probe, dict) else None

lines = [
    "# 微信全量验收报告",
    "",
    f"- 时间: {summary['timestamp']}",
    f"- 设备: `{dev}`",
    f"- Hook 可用: **{supports}**",
    f"- REST 矩阵: **{e2e_p}/{e2e_t}** ({summary['e2e_matrix'].get('success_rate', 'N/A')})",
    f"- Hook catalog: **{cat_p}/{cat_t}** ({summary['hook_catalog'].get('success_rate', 'N/A')})",
    "",
    "## 通道抽检",
    "",
]
for label, key in [("ping", "ping"), ("send_message", "send_message")]:
    d = summary.get(key, {})
    ch = d.get("channel_used") or (d.get("data") or {}).get("_channel_used", "")
    lines.append(f"- **{label}**: channel=`{ch}` code={d.get('code')}")

lines += ["", "## 微信实时数据摘要", ""]
hd = summary.get("hook_data", {}).get("data") or summary.get("hook_data", {})
if isinstance(hd, dict):
    for mod in ["wechat_version", "login_state", "profile", "hook_status", "process_info", "network_info"]:
        if mod in hd:
            lines.append(f"### {mod}")
            lines.append("```json")
            lines.append(json.dumps(hd[mod], ensure_ascii=False, indent=2)[:2000])
            lines.append("```")
            lines.append("")

if cat_path and cat.get("results"):
    failed = [r for r in cat["results"] if not r.get("success")]
    lines += ["## Hook catalog 失败项", ""]
    if not failed:
        lines.append("无（全部通过）")
    else:
        for r in failed[:50]:
            lines.append(f"- {r['action']}: {r.get('error','')[:120]}")

lines += ["", "## 原始文件", "", f"- JSON: `{out}`", f"- 日志: `${LOG}`"]
doc.write_text("\n".join(lines), encoding="utf-8")
print("REPORT_MD", doc)
print("E2E", e2e_p, e2e_t, "CATALOG", cat_p, cat_t)
PY

echo "=== 完成 ==="
echo "报告: ${REPORT_MD}"
echo "JSON: ${REPORT_JSON}"
