#!/bin/bash

NODE_BIN="/var/apps/nodejs_v22/target/bin/node"
SERVER_JS="${TRIM_APPDEST}/server/server.js"
DATA_DIR="${TRIM_PKGVAR}"
PORT="${TRIM_SERVICE_PORT:-8686}"
LOG_FILE="${DATA_DIR}/info.log"
PID_FILE="${DATA_DIR}/app.pid"

log_msg() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "${LOG_FILE}"
}

fail_msg() {
    log_msg "$1"
    [ -n "${TRIM_TEMP_LOGFILE}" ] && echo "$1" > "${TRIM_TEMP_LOGFILE}"
}

check_process() {
    kill -0 "$1" 2>/dev/null
}

status() {
    if [ -f "${PID_FILE}" ]; then
        pid=$(head -n 1 "${PID_FILE}" | tr -d '[:space:]')
        if [ -n "${pid}" ] && check_process "${pid}"; then
            return 0
        fi
        rm -f "${PID_FILE}"
    fi
    return 1
}

start_process() {
    if status; then
        return 0
    fi
    mkdir -p "${DATA_DIR}"
    if [ ! -x "${NODE_BIN}" ]; then
        fail_msg "未找到 Node.js 22 运行环境，请在应用中心安装 Node.js v22 后重试"
        return 1
    fi
    # 内置 SQLite 在 Node 22.13 之前需要开启实验参数
    NODE_FLAGS=""
    if ! "${NODE_BIN}" -e "require('node:sqlite')" >/dev/null 2>&1; then
        NODE_FLAGS="--experimental-sqlite"
        if ! "${NODE_BIN}" ${NODE_FLAGS} -e "require('node:sqlite')" >/dev/null 2>&1; then
            fail_msg "当前 Node.js 版本过低（需 22.5 及以上），请在应用中心更新 Node.js v22"
            return 1
        fi
    fi

    log_msg "Starting x.erp on port ${PORT} ..."
    nohup "${NODE_BIN}" ${NODE_FLAGS} "${SERVER_JS}" --data "${DATA_DIR}" --port "${PORT}" \
        --admin-password-file "${DATA_DIR}/admin-password" >> "${LOG_FILE}" 2>&1 &
    printf "%s" "$!" > "${PID_FILE}"

    # 等待服务端监听端口，启动失败时及时报错
    local count=0
    while [ $count -lt 15 ]; do
        sleep 1
        if ! status; then
            fail_msg "x.erp 启动失败，请查看日志 ${LOG_FILE}（常见原因：端口 ${PORT} 被占用）"
            return 1
        fi
        if (exec 3<>/dev/tcp/127.0.0.1/${PORT}) 2>/dev/null; then
            log_msg "Started, pid=$(cat "${PID_FILE}")"
            return 0
        fi
        count=$((count + 1))
    done
    log_msg "Port not ready after 15s, but process is running"
    return 0
}

stop_process() {
    if [ -r "${PID_FILE}" ]; then
        pid=$(head -n 1 "${PID_FILE}" | tr -d '[:space:]')
        if [ -n "${pid}" ] && check_process "${pid}"; then
            log_msg "Stopping pid ${pid} ..."
            kill -TERM "${pid}" 2>/dev/null
            local count=0
            while check_process "${pid}" && [ $count -lt 10 ]; do
                sleep 1
                count=$((count + 1))
            done
            check_process "${pid}" && kill -KILL "${pid}" 2>/dev/null
        fi
        rm -f "${PID_FILE}"
    fi
    return 0
}

case $1 in
start)
    start_process || exit 1
    ;;
stop)
    stop_process
    ;;
status)
    if status; then exit 0; else exit 3; fi
    ;;
*)
    exit 1
    ;;
esac
exit 0
