#!/bin/bash
# IPTV Manager - 启停控制脚本
# 用法: main start|stop|status
APP_NAME="iptv-manager"
PYTHON="$(command -v python3.12 || command -v python3)"

# 读取持久化配置（向导端口等）
PORT="${TRIM_SERVICE_PORT:-8082}"
[ -r "$TRIM_PKGETC/config.conf" ] && . "$TRIM_PKGETC/config.conf"
[ -n "${web_port}" ] && PORT="${web_port}"

RUN_USER="${TRIM_RUN_USERNAME:-${TRIM_USERNAME:-root}}"
RUN_GROUP="${TRIM_GROUPNAME:-root}"
PID_FILE="$TRIM_PKGVAR/app.pid"
LOG_FILE="$TRIM_PKGVAR/manager.log"

_is_python_pid() {
    # 只认 python 解释器进程：排除命令行恰好含脚本名的 shell/编辑器等误命中
    local comm
    comm=$(cat "/proc/$1/comm" 2>/dev/null) || return 1
    case "$comm" in
        python*) return 0 ;;
        *) return 1 ;;
    esac
}

_pid_in_webapp() {
    # 进一步要求 cwd 就是本应用的 webapp 目录，避免误伤其它 python 应用
    local cwd
    cwd=$(readlink "/proc/$1/cwd" 2>/dev/null) || return 1
    [ -n "$TRIM_APPDEST" ] && [ "$cwd" = "$TRIM_APPDEST/iptv-api/webapp" ]
}

_find_pids() {
    # $1 = 脚本名正则（app\.py / run_once\.py）：python 进程 + cwd 双重校验
    local pid out=""
    for pid in $(pgrep -f "$1" 2>/dev/null); do
        _is_python_pid "$pid" || continue
        _pid_in_webapp "$pid" || continue
        out="$out $pid"
    done
    [ -n "$out" ] && echo $out
    return 0
}

get_pids() {
    # 优先 pidfile（并校验确实是本应用的 python 进程，避免 PID 复用误判）
    if [ -r "$PID_FILE" ]; then
        local p
        p=$(cat "$PID_FILE" 2>/dev/null)
        if [ -n "$p" ] && kill -0 "$p" 2>/dev/null \
           && _is_python_pid "$p" && _pid_in_webapp "$p"; then
            echo "$p"
            return 0
        fi
    fi
    _find_pids "app\.py"
}

do_start() {
    local pids
    pids=$(get_pids)
    if [ -n "$pids" ]; then
        echo "already running (pid: $pids)"
        exit 0
    fi
    # 确保 python 存在
    if [ -z "$PYTHON" ] || [ ! -x "$PYTHON" ]; then
        for c in /usr/local/bin/python3.12 /usr/bin/python3.12 /usr/local/bin/python3 /usr/bin/python3; do
            [ -x "$c" ] && PYTHON="$c" && break
        done
    fi
    if [ -z "$PYTHON" ]; then
        [ -n "$TRIM_TEMP_LOGFILE" ] && echo "未找到可用的 Python3 解释器" >> "$TRIM_TEMP_LOGFILE"
        exit 1
    fi

    mkdir -p "$TRIM_PKGVAR/config" "$TRIM_PKGVAR/output/log" "$TRIM_PKGVAR/etc" 2>/dev/null

    # 首次安装：把出厂配置同步到可写数据区（不覆盖已有配置）
    if [ ! -f "$TRIM_PKGVAR/config/config.ini" ] && [ -f "$TRIM_APPDEST/iptv-api/config/config.ini" ]; then
        cp -a "$TRIM_APPDEST/iptv-api/config/." "$TRIM_PKGVAR/config/" 2>/dev/null
    fi

    local envexec=""
    if command -v setpriv >/dev/null 2>&1 && [ "$(id -u)" = "0" ] && [ "$RUN_USER" != "root" ]; then
        envexec="setpriv --reuid=$RUN_USER --regid=$RUN_GROUP --init-groups --inh-caps=-all --"
    fi

    cd "$TRIM_APPDEST/iptv-api/webapp" || exit 1
    env \
        TRIM_APPDEST="$TRIM_APPDEST" \
        TRIM_PKGVAR="$TRIM_PKGVAR" \
        TRIM_SERVICE_PORT="$PORT" \
        PYTHONPATH="$TRIM_APPDEST/pylibs" \
        LANGUAGE=zh_CN \
        ${GIT_CREDENTIALS_FILE:+GIT_CREDENTIALS_FILE="$GIT_CREDENTIALS_FILE"} \
        $envexec "$PYTHON" -u app.py >> "$LOG_FILE" 2>&1 &
    local pid=$!
    echo "$pid" > "$PID_FILE"

    # 等待端口就绪（最多 10 秒）
    local i=0
    while [ $i -lt 10 ]; do
        sleep 1
        if ! kill -0 "$pid" 2>/dev/null; then
            [ -n "$TRIM_TEMP_LOGFILE" ] && tail -5 "$LOG_FILE" >> "$TRIM_TEMP_LOGFILE" 2>/dev/null
            exit 1
        fi
        if command -v curl >/dev/null 2>&1 && curl -s -m 2 -o /dev/null "http://127.0.0.1:$PORT/"; then
            break
        fi
        i=$((i+1))
    done
    echo "started (pid: $pid, port: $PORT)"
    exit 0
}

do_stop() {
    local pids
    pids=$(get_pids)
    if [ -z "$pids" ]; then
        rm -f "$PID_FILE"
        echo "not running"
        exit 0
    fi
    # 优雅停：先 TERM 测速子进程再停面板（同样双重校验，避免误杀）
    for sp in $(_find_pids "run_once\.py"); do kill "$sp" 2>/dev/null; done
    kill $pids 2>/dev/null
    local i=0
    while [ $i -lt 8 ]; do
        sleep 1
        pids=$(get_pids)
        [ -z "$pids" ] && break
        i=$((i+1))
    done
    pids=$(get_pids)
    [ -n "$pids" ] && kill -9 $pids 2>/dev/null
    rm -f "$PID_FILE"
    echo "stopped"
    exit 0
}

do_status() {
    local pids
    pids=$(get_pids)
    if [ -n "$pids" ]; then
        echo "running (pid: $pids)"
        exit 0
    fi
    echo "stopped"
    exit 3
}

case "$1" in
    start)   do_start ;;
    stop)    do_stop ;;
    status)  do_status ;;
    *)       echo "usage: $0 {start|stop|status}"; exit 1 ;;
esac
