#!/usr/bin/env bash
# ─────────────────────────────────────────────────────────────────────────────
# 工作手机 · 无 USB 无线主控一键脚本（WiFi adb + 设备本机 stealth Frida + WS Agent）
#
# 解决：USB 线材/接口物理不稳反复掉线。改用 WiFi adb 传输，u2/frida 全走无线；
#       WS 身份仍用逻辑 device_id（SDK/hub 设备身份不变）。
#
# 真源：开发文档/10、项目管理/工作日志.md 2026-05-31 15:58 · 真机铁律 §〇.八 无线主控
#
# 用法：
#   bash wireless_master_oneclick.sh [USB_SERIAL] [SDK_HOST:PORT] [WIFI_PORT]
#   - USB_SERIAL  : 首次开 tcpip 用的 USB 序列（默认 xgfe65eimrrofyws）
#   - SDK_HOST    : SDK 地址（默认 127.0.0.1:8899）
#   - WIFI_PORT   : adb tcpip 端口（默认 5555）
#
# 前置：设备已 Root、已装 frida（phantom_frida_config.json 指向 stealth 二进制），
#       Mac 与设备同一 WiFi。USB 仅首次开 tcpip 时短暂连接，之后可拔线。
# ─────────────────────────────────────────────────────────────────────────────
set -uo pipefail

USB_SERIAL="${1:-xgfe65eimrrofyws}"
SDK_HOST="${2:-127.0.0.1:8899}"
WIFI_PORT="${3:-5555}"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
AGENT_DIR="$(cd "${SCRIPT_DIR}/../agent" && pwd)"
PHANTOM_CFG="${SCRIPT_DIR}/anti_detect/phantom_frida_config.json"
DEVICE_ID="${USB_SERIAL}"   # 逻辑 device_id（WS 身份），全程不变
export ANDROID_ADB_SERVER_PORT="${ANDROID_ADB_SERVER_PORT:-5038}"

adb() {
  command adb -P "${ANDROID_ADB_SERVER_PORT}" "$@"
}

log(){ echo "[$(date +%H:%M:%S)] $*"; }
fatal(){ echo "[FATAL] $*" >&2; exit 1; }

# ── 1. 经 USB 开 tcpip 并取设备 WiFi IP ──────────────────────────────────────
log "① 经 USB(${USB_SERIAL}) 开启 adb tcpip ${WIFI_PORT} 并取 WiFi IP"
WIFI_IP="$(adb -s "${USB_SERIAL}" shell ip route 2>/dev/null | grep -oE 'src [0-9.]+' | awk '{print $2}' | head -1)"
if [[ -z "${WIFI_IP}" ]]; then
  # 设备可能已是 WiFi adb，尝试从已连接条目取
  WIFI_IP="$(adb devices | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:'"${WIFI_PORT}"'' | head -1 | cut -d: -f1)"
fi
[[ -n "${WIFI_IP}" ]] || fatal "无法获取设备 WiFi IP（确认设备已连 WiFi 且 USB 可见，或已 adb connect）"
log "   设备 WiFi IP=${WIFI_IP}"
adb -s "${USB_SERIAL}" tcpip "${WIFI_PORT}" >/dev/null 2>&1 || true
sleep 3

# ── 2. adb connect WiFi + 稳定性校验 ────────────────────────────────────────
WIFI_SERIAL="${WIFI_IP}:${WIFI_PORT}"
log "② adb connect ${WIFI_SERIAL}"
adb connect "${WIFI_SERIAL}" >/dev/null 2>&1
sleep 2
OK=0
for i in 1 2 3 4; do
  [[ "$(adb -s "${WIFI_SERIAL}" shell echo ok 2>/dev/null | tr -d '\r')" == "ok" ]] && OK=$((OK+1))
  sleep 1
done
log "   WiFi adb 稳定 ${OK}/4"
[[ "${OK}" -ge 3 ]] || fatal "WiFi adb 不稳定（${OK}/4），请检查同网/路由"

# ── 3. 启动设备本机 stealth frida-server（按 phantom 配置端口/二进制）──────────
FRIDA_PORT="$(python3 -c "import json;print(json.load(open('${PHANTOM_CFG}'))['listen_port'])" 2>/dev/null || echo 27042)"
FRIDA_BIN="$(python3 -c "import json;print(json.load(open('${PHANTOM_CFG}'))['binary_path'])" 2>/dev/null || echo /data/local/tmp/frida-server-16)"
FRIDA_BASE="$(basename "${FRIDA_BIN}")"
log "③ 重启本机 stealth frida ${FRIDA_BIN} @ ${FRIDA_PORT}（setsid 脱离会话）"
adb -s "${WIFI_SERIAL}" shell "su -c 'pkill -f ${FRIDA_BASE} 2>/dev/null; pkill -f frida-server 2>/dev/null; true'" >/dev/null 2>&1 || true
sleep 1
adb -s "${WIFI_SERIAL}" shell "su -c 'setsid ${FRIDA_BIN} -l 0.0.0.0:${FRIDA_PORT} </dev/null >/dev/null 2>&1 &'" >/dev/null 2>&1
sleep 4
adb -s "${WIFI_SERIAL}" shell "su -c 'ps -A | grep ${FRIDA_BASE}'" 2>/dev/null | head -1 \
  || fatal "frida 进程未确认"
adb -s "${WIFI_SERIAL}" forward "tcp:${FRIDA_PORT}" "tcp:${FRIDA_PORT}" >/dev/null

# ── 4. 确保微信运行（温和 am start，不 frida-spawn）─────────────────────────
if [[ -z "$(adb -s "${WIFI_SERIAL}" shell pidof com.tencent.mm 2>/dev/null | tr -d '\r')" ]]; then
  log "④ 拉起微信（am start，禁 frida-spawn）"
  adb -s "${WIFI_SERIAL}" shell am start -n com.tencent.mm/.ui.LauncherUI >/dev/null 2>&1 || true
  sleep 5
fi

# ── 5. 启动 Agent（WP_DEVICE_SERIAL=WiFi 序列，device_id=逻辑身份）───────────
log "⑤ 启动 Agent：device_id=${DEVICE_ID}（WS身份） / adb_serial=${WIFI_SERIAL}（u2/frida传输）"
pkill -f "agent.py -d ${DEVICE_ID}" 2>/dev/null || true
sleep 2
WIRELESS_LOG="${SCRIPT_DIR}/../logs/wireless_agent.log"
: > "${WIRELESS_LOG}"
AGENT_PID="$(
  cd "${AGENT_DIR}"
  export WP_DEVICE_SERIAL="${WIFI_SERIAL}"
  export WP_FRIDA_MODE=remote
  export WP_FRIDA_PORT="${FRIDA_PORT}"
  export WORKPHONE_AGENT_LOG="${WIRELESS_LOG}"
  export WORKPHONE_WS_URL="ws://${SDK_HOST}/ws/device"
  export WORKPHONE_DEVICE_ID="${DEVICE_ID}"
  python3 - <<'PY'
import os
import subprocess
import sys

cmd = [
    sys.executable,
    "agent.py",
    "-d",
    os.environ["WORKPHONE_DEVICE_ID"],
    "-s",
    os.environ["WORKPHONE_WS_URL"],
    "--heartbeat",
    "10",
]
with open(os.environ["WORKPHONE_AGENT_LOG"], "ab", buffering=0) as log:
    proc = subprocess.Popen(
        cmd,
        cwd=os.getcwd(),
        env=os.environ.copy(),
        stdin=subprocess.DEVNULL,
        stdout=log,
        stderr=subprocess.STDOUT,
        start_new_session=True,
        close_fds=True,
    )
print(proc.pid)
PY
)"
echo "${AGENT_PID}" > "${SCRIPT_DIR}/../logs/wireless_agent.pid"
log "   Agent pid=${AGENT_PID}（日志 ${WIRELESS_LOG}）"

for _i in $(seq 1 45); do
  if ! kill -0 "${AGENT_PID}" 2>/dev/null; then
    tail -80 "${WIRELESS_LOG}" >&2 || true
    fatal "Agent 启动后退出"
  fi
  if grep -q "RPC ping: pong" "${WIRELESS_LOG}" 2>/dev/null && \
     grep -q "服务器确认注册" "${WIRELESS_LOG}" 2>/dev/null; then
    log "   Agent WS + Frida RPC 已就绪"
    break
  fi
  sleep 2
done

# ── 6. 验证无线 Hook 链路 ───────────────────────────────────────────────────
log "⑥ 验证无线 Hook（get_profile）"
RESP="$(curl -s -m 45 -X POST "http://${SDK_HOST}/api/v3/hook/execute" \
  -H 'Content-Type: application/json' \
  -d "{\"device_id\":\"${DEVICE_ID}\",\"platform\":\"wechat\",\"action\":\"get_profile\",\"params\":{},\"hook_only\":true}")"
echo "${RESP}" | head -c 300; echo
OK="$(echo "${RESP}" | python3 -c 'import json,sys
try:
    d=json.load(sys.stdin)
    print(bool((d.get("data") or {}).get("success") or d.get("success")))
except Exception:
    print(False)' 2>/dev/null || echo False)"
CH="$(echo "${RESP}" | python3 -c 'import json,sys
try:
    d=json.load(sys.stdin)
    print(d.get("channel_used") or (d.get("data") or {}).get("channel") or "")
except Exception:
    print("")' 2>/dev/null || true)"
if [[ "${OK}" == "True" ]] && echo "${CH}" | grep -Eqi 'frida|hook'; then
  log "✅ 无 USB 无线主控就绪：WiFi adb + 本机 stealth frida + WS + Hook"
  log "   现在可拔掉 USB 线，控制/取材料经 WiFi 无线进行。"
else
  tail -80 "${WIRELESS_LOG}" >&2 || true
  fatal "Hook 未确认成功（frida attach / 微信运行 / 端口转发）"
fi
log "USB 掉线无影响；如换网/IP 变化，重跑本脚本即可。"
