#!/bin/bash
# main：应用的启动 / 停止 / 状态查询。
#
# 退出码：0 = 成功或运行中；1 = 失败；3 = status 时表示未运行。
set -uo pipefail

TP_HOOK=main
SELF_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=lib.sh
. "$SELF_DIR/lib.sh"

PID_FILE="${TRIM_PKGVAR:-/tmp}/app.pid"

is_running() {
    local pid
    [ -f "$PID_FILE" ] || return 1
    pid="$(head -n 1 "$PID_FILE" 2>/dev/null | tr -d '[:space:]')"
    [ -n "$pid" ] || return 1
    if tp_pid_is_ours "$pid"; then
        return 0
    fi
    rm -f "$PID_FILE" 2>/dev/null
    return 1
}

start_process() {
    if is_running; then
        tp_log main "进程已在运行，跳过启动"
        return 0
    fi

    local bin data app_dest
    bin="$(tp_select_binary)" || return 1
    data="$(tp_data_dir)" || return 1
    app_dest="$(tp_app_dest)"

    # 控制台日志：每次启动一份，保留最近 5 份。
    local console_log="$data/logs/console-$(date +%Y%m%d-%H%M%S).log"
    mkdir -p "$data/logs" 2>/dev/null || true
    : >> "$console_log"
    ls -1t "$data/logs"/console-*.log 2>/dev/null | tail -n +6 | while read -r old; do
        rm -f "$old"
    done

    # 兜底建目录（手工拷贝文件、跳过安装流程时也能起来）。
    mkdir -p "$data/logs" "$data/backup" "$data/tmp" 2>/dev/null || true

    local args=(
        serve
        --data "$data"
        --socket "$app_dest/totpilot.sock"
    )
    if [ -n "${TP_DEV_ADDR:-}" ]; then
        args=(serve --data "$data" --dev "$TP_DEV_ADDR")
    fi

    local user
    user="$(tp_app_user)"

    tp_log main "启动：$bin ${args[*]}"
    # root 且配了应用用户时 runuser 会 exec 进目标程序，$! 仍是目标进程 pid。
    if [ "$(id -u)" -eq 0 ] && [ -n "$user" ] && command -v runuser >/dev/null 2>&1; then
        runuser -u "$user" -- "$bin" "${args[@]}" >> "$console_log" 2>&1 &
    else
        "$bin" "${args[@]}" >> "$console_log" 2>&1 &
    fi
    local pid=$!
    printf '%s' "$pid" > "$PID_FILE"

    # 启动存活校验：最多等 5 秒。
    local waited=0
    while [ "$waited" -lt 5 ]; do
        sleep 1
        waited=$((waited + 1))
        if ! kill -0 "$pid" 2>/dev/null; then
            tp_log main "进程在 ${waited}s 内退出，启动失败"
            rm -f "$PID_FILE" 2>/dev/null
            tp_user_error "令牌中枢启动失败，详情见 $console_log"
            return 1
        fi
    done

    printf '%s' "$pid" > "$PID_FILE"
    tp_log main "启动成功，pid=$pid"
    return 0
}

stop_process() {
    if ! is_running; then
        tp_log main "进程未运行，无需停止"
        rm -f "$PID_FILE" 2>/dev/null
        return 0
    fi
    local pid
    pid="$(head -n 1 "$PID_FILE" | tr -d '[:space:]')"

    tp_log main "发送 TERM 给 pid=$pid"
    kill -TERM "$pid" 2>/dev/null

    local waited=0
    while tp_pid_is_ours "$pid" && [ "$waited" -lt 20 ]; do
        sleep 1
        waited=$((waited + 1))
        [ $((waited % 5)) -eq 0 ] && tp_log main "等待退出…(${waited}s/20s)"
    done

    if tp_pid_is_ours "$pid"; then
        tp_log main "超时未退出，发送 KILL"
        kill -KILL "$pid" 2>/dev/null
        sleep 1
    else
        tp_log main "进程已退出"
    fi
    rm -f "$PID_FILE" 2>/dev/null
    return 0
}

case "${1:-}" in
start)
    start_process
    exit $?
    ;;
stop)
    stop_process
    exit $?
    ;;
status)
    if is_running; then
        exit 0
    fi
    exit 3
    ;;
*)
    tp_log main "未知子命令：${1:-（空）}"
    tp_user_error "内部错误：未知的运行控制命令"
    exit 1
    ;;
esac
