#!/bin/bash

set -u

LOG_FILE="${TRIM_PKGVAR}/info.log"
PID_FILE="${TRIM_PKGVAR}/app.pid"
GATEWAY_SOCKET="${TRIM_APPDEST:-}/app.sock"
# 须与 app/ui/config 中的 gatewayPrefix 一致
GATEWAY_PREFIX="/app/FnMessageBot"

# write the command to start your program here 
_app_install_root() {
    local src="${BASH_SOURCE[0]:-$0}"
    cd -P "$(dirname "${src}")/.." && pwd
}

resolve_app_code_dir() {
    local root cmd_dir trim_dest d
    root="$(_app_install_root)"
    cmd_dir="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    trim_dest="${TRIM_APPDEST:-}"

    for d in \
        "${cmd_dir}/fnmessagebots" \
        "${root}/app/server" \
        "${root}/target" \
        "${root}/target/fnmessagebots"
    do
        if [ -f "${d}/requirements.txt" ] && [ -f "${d}/src/main.py" ]; then
            printf "%s" "${d}"
            return 0
        fi
    done

    if [ -n "${trim_dest}" ]; then
        for d in \
            "${trim_dest}/target" \
            "${trim_dest}/target/fnmessagebots" \
            "${trim_dest}/app/server"
        do
            if [ -f "${d}/requirements.txt" ] && [ -f "${d}/src/main.py" ]; then
                printf "%s" "${d}"
                return 0
            fi
        done
    fi
    return 1
}


fail_user_visible() {
    local msg="$1"
    if [ -n "${TRIM_TEMP_LOGFILE:-}" ]; then
        printf "%s\n" "${msg}" > "${TRIM_TEMP_LOGFILE}"
    fi
    exit 1
}

log_msg() {
    mkdir -p "${TRIM_PKGVAR}" 2>/dev/null || true
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "${LOG_FILE}"
}

start_process() {
    if status; then
        return 0
    fi

    log_msg "Starting process ..."
    local app_code_dir app_main py pypath ui_port
    source "$(dirname "${BASH_SOURCE[0]}")/ui_port" || fail_user_visible "启动失败：缺少端口配置脚本，请重新安装。"
    ui_port="$(read_fnmb_ui_port)" || return 1
    app_code_dir="$(resolve_app_code_dir)" || fail_user_visible "启动失败：未找到应用代码，请重新安装。"
    app_main="${app_code_dir}/src/main.py"
    if [ -x "${TRIM_PKGVAR}/venv/bin/python" ] && [ ! -f "${TRIM_PKGVAR}/.use_python_target" ]; then
        py="${TRIM_PKGVAR}/venv/bin/python"
        pypath="${app_code_dir}"
    elif [ -f "${TRIM_PKGVAR}/.use_python_target" ] && [ -d "${TRIM_PKGVAR}/python_modules" ]; then
        py="python3"
        pypath="${app_code_dir}:${TRIM_PKGVAR}/python_modules"
    else
        fail_user_visible "启动失败：未安装依赖（无 venv 且无 python_modules），请重新安装应用。"
    fi
    # 在子进程中直接 exec，不拼接 shell 命令；记录的 PID 就是 Python PID。
    (
        export APP_HOME="${TRIM_PKGVAR}" UI_HOST="127.0.0.1" UI_PORT="${ui_port}"
        export FNMB_GATEWAY_SOCKET="${GATEWAY_SOCKET}" FNMB_GATEWAY_PREFIX="${GATEWAY_PREFIX}"
        export PYTHONUNBUFFERED=1 PYTHONPATH="${pypath}"
        cd "${TRIM_PKGVAR}" || exit 1
        exec "${py}" -u "${app_main}"
    ) >> "${LOG_FILE}" 2>&1 &
    # write pid to pidfile
    printf "%s" "$!" > "${PID_FILE}"
    # log_msg "CMD = ${CMD}"
    # log_msg "pid = $!"
    return 0
}

stop_process() {
    log_msg "Stopping process ..."

    if [ -r "${PID_FILE}" ]; then
        pid=$(head -n 1 "${PID_FILE}" | tr -d '[:space:]')
        
        log_msg "pid=${pid}"
        if ! check_process "${pid}"; then
            # process not exist, delete pidfile
            rm -f "${PID_FILE}"
            log_msg "remove pid file 1"
            return
        fi

        log_msg "send TERM signal to PID:${pid}..."
        kill -TERM ${pid} >> "${LOG_FILE}" 2>&1

        local count=0
        while check_process "${pid}" && [ $count -lt 10 ]; do
            sleep 1
            count=$((count + 1))
            log_msg "waiting process terminal... (${count}s/10s)"
        done

        if check_process "${pid}"; then
            log_msg "send KILL signal to PID:${pid}..."
            kill -KILL "${pid}"
            sleep 1
            rm -f "${PID_FILE}"
        else
            log_msg "process killed... "
        fi
    fi
    rm -f "${PID_FILE}"
    rm -f "${GATEWAY_SOCKET}" 2>/dev/null || true

    return 0
}

check_process() {
    local pid=$1
    case "$pid" in ""|*[!0-9]*|0|1) return 1 ;; esac
    if kill -0 "${pid}" 2>/dev/null; then
        return 0  # process exist
    else
        return 1  # process not exist
    fi
}

status() {
    if [ -f "${PID_FILE}" ]; then
        pid=$(head -n 1 "${PID_FILE}" | tr -d '[:space:]')
        if check_process "${pid}"; then
            return 0
        else
            # Process is not running but pidfile exists - clean it up
            rm -f "${PID_FILE}"
        fi    
    fi

    return 1
}

case $1 in
start)
    # run start command. exit 0 if success, exit 1 if failed
    start_process
    exit $?
    ;;
stop)
    # run stop command. exit 0 if success, exit 1 if failed
    stop_process
    exit $?
    ;;
status)
    # check application status command. exit 0 if running, exit 3 if not running
    if status; then 
        exit 0
    else 
        exit 3
    fi
    ;;
*)
    exit 1
    ;;
esac
