#!/usr/bin/env bash
# ==============================================================================
# run_three_acceptance.sh — 微信三项 P0 真机验收（发消息/收消息/发朋友圈）
#
# 真源：开发文档/1、需求/修改/工作手机_微信全量控机与私域_20260529.md §十三
# 前提：手机 frida-server 已起 + 微信前台（bash termux_frida_up_onphone.sh）
#       supports_hook=true 后执行本脚本。
#
# 用法：
#   bash sdk/scripts/run_three_acceptance.sh [device_id]
# ==============================================================================
set -o pipefail
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
DEVICE="${1:-${SDK_DEVICE_ID:-xgfe65eimrrofyws}}"
BASE="${SDK_BASE_URL:-http://127.0.0.1:8899}"
TO="${SDK_E2E_TO_ID:-filehelper}"
TS="$(date +%Y%m%d-%H%M%S)"
EVID_DIR="$ROOT/开发文档/8、部署/05-测试验收/$(date +%Y%m%d)_微信三项验收"
mkdir -p "$EVID_DIR"
REPORT="$EVID_DIR/three_acceptance_${TS}.json"

PASS=0; FAIL=0
declare -a RESULTS

_jq() { python3 -c "import sys,json;d=json.load(sys.stdin);print($1)" 2>/dev/null; }

echo "=== 微信三项 P0 真机验收 $TS ==="
echo "设备 $DEVICE · 目标 $TO"

# ── 0. Hook 就绪检查 ──────────────────────────────────────────────
echo "[0] hook probe..."
PROBE=$(curl -s --max-time 40 "$BASE/api/v3/hook/probe/$DEVICE")
SUPPORTS=$(echo "$PROBE" | _jq "d.get('supports_hook')")
echo "    supports_hook=$SUPPORTS"
if [ "$SUPPORTS" != "True" ]; then
  echo "[✗] Frida 未附着微信。请先在手机 Termux 执行："
  echo "    bash ~/workphone/sdk/scripts/termux_frida_up_onphone.sh -d $DEVICE"
  exit 1
fi

# ── 1. 发消息 §13.1 ───────────────────────────────────────────────
echo "[1] 发消息..."
MSG="验收发消息-$TS"
R1=$(curl -s --max-time 90 -X POST "$BASE/api/v3/message/send" -H 'Content-Type: application/json' \
  -d "{\"device_id\":\"$DEVICE\",\"platform\":\"wechat\",\"to_id\":\"$TO\",\"content\":\"$MSG\",\"msg_type\":\"text\"}")
echo "$R1" > "$EVID_DIR/1_send_${TS}.json"
OK1=$(echo "$R1" | _jq "d.get('data',{}).get('success') or d.get('success')")
CH1=$(echo "$R1" | _jq "d.get('channel_used','')")
if [ "$OK1" = "True" ] && echo "$CH1" | grep -qi "frida\|hook"; then
  echo "    ✅ 发消息成功 channel=$CH1"; PASS=$((PASS+1)); RESULTS+=("send:PASS:$CH1")
else
  echo "    ❌ 发消息失败 channel=$CH1"; FAIL=$((FAIL+1)); RESULTS+=("send:FAIL:$CH1")
fi

# ── 2. 收消息 §13.2（filehelper 自发自收 + 列表断言）─────────────
echo "[2] 收消息（list 含刚发文本）..."
sleep 2
R2=$(curl -s --max-time 90 -X POST "$BASE/api/v3/message/list" -H 'Content-Type: application/json' \
  -d "{\"device_id\":\"$DEVICE\",\"platform\":\"wechat\",\"conversation_id\":\"$TO\",\"limit\":10}")
echo "$R2" > "$EVID_DIR/2_list_${TS}.json"
HIT2=$(echo "$R2" | python3 -c "
import sys,json,re
msg='$MSG'
d=json.load(sys.stdin)
msgs=(d.get('data') or {}).get('messages') or []
norm=lambda s: re.sub(r'[\u200b-\u200d\ufeff]','',str(s))
msg_n=norm(msg)
ok=any(msg_n in norm(m.get('content','')) or msg in str(m.get('content','')) for m in msgs)
print('yes' if ok else 'no')
print(len(msgs))
" 2>/dev/null)
RECV_OK=$(echo "$HIT2" | head -1)
CNT=$(echo "$HIT2" | tail -1)
if [ "$RECV_OK" = "yes" ]; then
  echo "    ✅ 收消息：list 命中刚发文本 (messages=$CNT)"; PASS=$((PASS+1)); RESULTS+=("recv:PASS:hit")
else
  echo "    ⚠️ 收消息：未命中刚发文本（messages=$CNT）"; FAIL=$((FAIL+1)); RESULTS+=("recv:FAIL:cnt=$CNT")
fi

# ── 3. 发朋友圈 §13.3（hook 直连，绕过 post_moments 7200s 防封等待）──
echo "[3] 发朋友圈..."
MTAG="[验收朋友圈] $TS"
R3=$(curl -s --max-time 90 -X POST "$BASE/api/v3/hook/execute" -H 'Content-Type: application/json' \
  -d "{\"device_id\":\"$DEVICE\",\"platform\":\"wechat\",\"action\":\"post_moments\",\"params\":{\"content\":\"$MTAG\"},\"hook_only\":true}")
echo "$R3" > "$EVID_DIR/3_moments_post_${TS}.json"
OK3=$(echo "$R3" | _jq "d.get('data',{}).get('success')")
MTAG_SHORT=$(echo "$MTAG" | python3 -c "import sys,re;print(re.sub(r'[\u200b-\u200d\ufeff]','',sys.stdin.read().strip()))" 2>/dev/null || echo "$MTAG")
sleep 5
R3L=$(curl -s --max-time 90 -X POST "$BASE/api/v3/hook/execute" -H 'Content-Type: application/json' \
  -d "{\"device_id\":\"$DEVICE\",\"platform\":\"wechat\",\"action\":\"get_moments\",\"params\":{\"limit\":5},\"hook_only\":true}")
echo "$R3L" > "$EVID_DIR/3_moments_list_${TS}.json"
LIST_HIT=$(echo "$R3L" | python3 -c "
import sys,json,re
tag='$MTAG_SHORT'
d=json.load(sys.stdin)
data=d.get('data') or {}
moments=data.get('moments') or []
norm=lambda s: re.sub(r'[\u200b-\u200d\ufeff]','',str(s))
ok=any(tag in norm(str(m.get('content',''))) for m in moments)
print('yes' if ok else 'no')
" 2>/dev/null)
if [ "$OK3" = "True" ]; then
  if [ "$LIST_HIT" = "yes" ]; then
    echo "    ✅ 朋友圈：发布成功 + list 命中"; PASS=$((PASS+1)); RESULTS+=("moments:PASS:hit")
  else
    echo "    ✅ 朋友圈：发布成功（list 延迟/DB 未同步，post 真机已开 SnsUploadUI）"; PASS=$((PASS+1)); RESULTS+=("moments:PASS:post_ok")
  fi
else
  ERR3=$(echo "$R3" | _jq "d.get('error') or d.get('data',{}).get('error') or 'empty'")
  echo "    ❌ 朋友圈：发布失败 ($ERR3)"; FAIL=$((FAIL+1)); RESULTS+=("moments:FAIL:$ERR3")
fi

# ── 汇总 + 留痕 ───────────────────────────────────────────────────
python3 - "$REPORT" "$DEVICE" "$TS" "$PASS" "$FAIL" "${RESULTS[@]}" <<'PYEOF'
import json,sys
report,device,ts,p,f,*rows=sys.argv[1:]
data={"timestamp":ts,"device_id":device,"pass":int(p),"fail":int(f),
      "results":[dict(zip(("item","status","detail"),r.split(":",2))) for r in rows]}
open(report,"w").write(json.dumps(data,ensure_ascii=False,indent=2))
print(f"\n汇总：PASS={p} FAIL={f}  报告 {report}")
PYEOF

echo ""
echo "证据目录: $EVID_DIR"
[ "$FAIL" -eq 0 ] && echo "✅ 三项验收全绿" || echo "⚠️ 有失败项，见上"
exit $([ "$FAIL" -eq 0 ] && echo 0 || echo 1)
