#!/bin/bash
# 卸载前执行：彻底停止 Node 主进程、在线更新看门狗与 frps 子进程，
# 确保卸载完成后管理端口（默认 8080）与通信端口（9400）立即释放、无残留进程。
# fnOS 不一定先调用 main stop，因此这里自行做完整清理（幂等，可重复执行）。

DATA_ROOT="${TRIM_PKGVAR}"
WORK_DIR="${DATA_ROOT}/server"
PID_FILE="${DATA_ROOT}/app.pid"

wait_exit() {
    local pid="$1"
    local i
    for i in $(seq 1 10); do
        kill -0 "$pid" 2>/dev/null || return 0
        sleep 1
    done
    return 1
}

# 1. 优先走标准 stop（优雅退出并清理 frps/看门狗）。
CMD_MAIN="$(dirname "$TRIM_APPDEST")/cmd/main"
if [ -x "$CMD_MAIN" ]; then
    "$CMD_MAIN" stop >/dev/null 2>&1 || true
fi

# 2. pid 文件中的主进程兜底强杀。
if [ -f "$PID_FILE" ]; then
    pid=$(head -n 1 "$PID_FILE" | tr -d '[:space:]')
    if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
        kill -TERM "$pid" 2>/dev/null || true
        wait_exit "$pid" || kill -KILL "$pid" 2>/dev/null || true
    fi
    rm -f "$PID_FILE"
fi

# 3. 按本应用路径模式清理所有残留（Node、看门狗、frps）；路径含 xfserver，不误伤其它应用。
if command -v pgrep >/dev/null 2>&1; then
    for pattern in \
        "${WORK_DIR}/server/app.js" \
        "${DATA_ROOT}/data/server/updater.mjs" \
        "${WORK_DIR}/bin/frps"; do
        for p in $(pgrep -f "$pattern" 2>/dev/null); do
            kill -TERM "$p" 2>/dev/null || true
        done
    done
    # 旧版以相对入口启动，按进程工作目录（/proc/PID/cwd == WORK_DIR）精确补漏。
    if [ -d /proc ]; then
        for p in $(pgrep -f "experimental-sqlite" 2>/dev/null); do
            link=$(readlink "/proc/$p/cwd" 2>/dev/null || true)
            [ "$link" = "$WORK_DIR" ] && kill -TERM "$p" 2>/dev/null || true
        done
    fi
    sleep 2
    for pattern in \
        "${WORK_DIR}/server/app.js" \
        "${DATA_ROOT}/data/server/updater.mjs" \
        "${WORK_DIR}/bin/frps"; do
        for p in $(pgrep -f "$pattern" 2>/dev/null); do
            kill -KILL "$p" 2>/dev/null || true
        done
    done
    if [ -d /proc ]; then
        for p in $(pgrep -f "experimental-sqlite" 2>/dev/null); do
            link=$(readlink "/proc/$p/cwd" 2>/dev/null || true)
            [ "$link" = "$WORK_DIR" ] && kill -KILL "$p" 2>/dev/null || true
        done
    fi
fi

exit 0
