#!/bin/sh

PACKAGE_NAME="${SYNOPKG_PKGNAME:-ZFilePro}"
APP_DEST="${SYNOPKG_PKGDEST:-/var/packages/${PACKAGE_NAME}/target}"
APP_VAR="${SYNOPKG_PKGVAR:-/var/packages/${PACKAGE_NAME}/var}"
APP_HOME="${SYNOPKG_PKGHOME:-/var/packages/${PACKAGE_NAME}/home}"
APP_ETC="/var/packages/${PACKAGE_NAME}/etc"
BIN="${APP_DEST}/zfile/zfile-pro"
PID_FILE="${APP_VAR}/zfile.pid"
CONFIG_FILE="${APP_ETC}/application.properties"
CONSOLE_LOG="${APP_VAR}/logs/console.log"
SERVER_PORT="8899"

write_message() {
    if [ -n "${SYNOPKG_TEMP_LOGFILE:-}" ]; then
        printf '%s\n' "$1" > "$SYNOPKG_TEMP_LOGFILE"
    fi
}

read_pid() {
    [ -r "$PID_FILE" ] || return 1
    sed -n '1{s/[[:space:]]//g;p;}' "$PID_FILE"
}

process_running() {
    pid="$1"
    case "$pid" in
        ''|*[!0-9]*) return 1 ;;
    esac
    kill -0 "$pid" 2>/dev/null || return 1
    [ -r "/proc/${pid}/cmdline" ] || return 1
    tr '\000' ' ' < "/proc/${pid}/cmdline" | grep -F "$BIN" >/dev/null 2>&1
}

status_process() {
    pid="$(read_pid 2>/dev/null || true)"
    if process_running "$pid"; then
        return 0
    fi
    rm -f "$PID_FILE"
    return 1
}

readiness_probe_available() {
    command -v curl >/dev/null 2>&1 || command -v wget >/dev/null 2>&1 || command -v nc >/dev/null 2>&1
}

service_ready() {
    if command -v curl >/dev/null 2>&1; then
        curl --connect-timeout 1 --max-time 2 --silent --output /dev/null "http://127.0.0.1:${SERVER_PORT}/"
    elif command -v wget >/dev/null 2>&1; then
        wget -T 2 -t 1 -q -O /dev/null "http://127.0.0.1:${SERVER_PORT}/"
    else
        nc -z -w 2 127.0.0.1 "$SERVER_PORT" >/dev/null 2>&1
    fi
}

start_process() {
    if status_process; then
        return 0
    fi
    if [ ! -x "$BIN" ]; then
        write_message "ZFile Pro 可执行文件不存在或不可执行。"
        return 1
    fi
    if [ ! -f "$CONFIG_FILE" ]; then
        write_message "ZFile Pro 配置文件不存在，请重新安装套件。"
        return 1
    fi

    mkdir -p "$APP_VAR/db" "$APP_VAR/logs" "$APP_HOME"
    umask 077
    if [ -n "${LD_LIBRARY_PATH:-}" ]; then
        export LD_LIBRARY_PATH="${APP_DEST}/zfile:${LD_LIBRARY_PATH}"
    else
        export LD_LIBRARY_PATH="${APP_DEST}/zfile"
    fi
    export HOME="$APP_HOME"

    nohup "$BIN" \
        --spring.config.additional-location="optional:file:${CONFIG_FILE}" \
        --spring.web.resources.static-locations="file:${APP_DEST}/static/" \
        >> "$CONSOLE_LOG" 2>&1 &
    pid=$!
    printf '%s\n' "$pid" > "$PID_FILE"

    count=0
    while [ "$count" -lt 30 ]; do
        sleep 1
        if ! process_running "$pid"; then
            rm -f "$PID_FILE"
            write_message "ZFile Pro 启动失败，请查看 ${CONSOLE_LOG}。"
            return 1
        fi
        if readiness_probe_available && service_ready; then
            return 0
        fi
        count=$((count + 1))
    done

    if ! readiness_probe_available && process_running "$pid"; then
        return 0
    fi

    stop_process
    write_message "ZFile Pro 启动超时，端口 ${SERVER_PORT} 未就绪，请查看 ${CONSOLE_LOG}。"
    return 1
}

stop_process() {
    pid="$(read_pid 2>/dev/null || true)"
    if ! process_running "$pid"; then
        rm -f "$PID_FILE"
        return 0
    fi

    kill -TERM "$pid" 2>/dev/null || true
    count=0
    while process_running "$pid" && [ "$count" -lt 30 ]; do
        sleep 1
        count=$((count + 1))
    done
    if process_running "$pid"; then
        kill -KILL "$pid" 2>/dev/null || true
        sleep 1
    fi
    if process_running "$pid"; then
        write_message "ZFile Pro 进程无法停止，PID: ${pid}。"
        return 1
    fi
    rm -f "$PID_FILE"
    return 0
}

case "${1:-}" in
    start)
        start_process
        ;;
    stop)
        stop_process
        ;;
    status)
        if status_process; then
            exit 0
        fi
        exit 3
        ;;
    *)
        exit 1
        ;;
esac
