#!/bin/bash

LOG_FILE="${TRIM_PKGVAR}/info.log"
PID_FILE="${TRIM_PKGVAR}/app.pid"

# 配置文件路径（与飞牛向导配置一致）
CFG_FILE="${TRIM_APPDEST_VOL}/@appshare/${TRIM_APPNAME}/data/config.json"
# 配置文件目录（确保存在）
CFG_DIR=$(dirname "${CFG_FILE}")

# 从飞牛向导获取用户配置的变量（移除 postgres 相关无用变量，保留必要项）
DATABASE_USERNAME="$wizard_db_username"   # 数据库用户名（MySQL专属）
DATABASE_PASSWORD="$wizard_db_password"   # 数据库密码（MySQL专属）
DATABASE_TYPE="$wizard_database_type"     # 数据库类型（仅支持 sqlite/mysql）
DATABASE_HOST="$wizard_db_host"           # 数据库主机（MySQL专属）
DATABASE_NAME="$wizard_db_name"           # 数据库名称（MySQL专属）
DATABASE_PORT="$wizard_db_port"           # 数据库端口（MySQL专属）
APP_PORT="$wizard_app_port"               # 应用端口（向导配置，默认5238）

# 应用默认配置（可根据需求调整）
DEFAULT_BIND_HOST="0.0.0.0"               # 默认绑定所有网卡
DEFAULT_LOG_LEVEL="info"                  # 默认日志级别
DEFAULT_DATA_PATH="${TRIM_APPDEST_VOL}/@appshare/${TRIM_APPNAME}/data"  # 默认数据目录
SSL_CERT_FILE=""                          # SSL证书文件（未配置则不启用SSL）
SSL_KEY_FILE=""                           # SSL证书密钥（未配置则不启用SSL）
CUSTOM_UI_DIR=""                          # 自定义UI目录（未配置则使用默认）

# 启动命令（仅指定配置文件，所有参数通过JSON读取）
CMD="${TRIM_APPDEST}/bin/PanIndex -c=${CFG_FILE}"

# 日志输出函数：记录带时间戳的日志
log_msg() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> ${LOG_FILE}
}

# 初始化配置文件（若不存在则创建空JSON）
init_config_file() {
    if [ ! -d "${CFG_DIR}" ]; then
        mkdir -p "${CFG_DIR}"
        log_msg "创建配置文件目录：${CFG_DIR}"
    fi
    if [ ! -f "${CFG_FILE}" ]; then
        echo "{}" > "${CFG_FILE}"
        log_msg "创建空配置文件：${CFG_FILE}"
    fi
}

# 校验数据库类型是否支持（移除 postgres 支持）
validate_db_type() {
    case "${DATABASE_TYPE}" in
        sqlite|mysql)
            log_msg "检测到支持的数据库类型：${DATABASE_TYPE}"
            return 0
            ;;
        *)
            log_msg "错误：不支持的数据库类型 ${DATABASE_TYPE}，仅支持 sqlite/mysql"
            exit 1
            ;;
    esac
}

# 构建数据库DSN（根据数据库类型，移除 postgres 相关逻辑）
build_db_dsn() {
    local dsn=""
    case "${DATABASE_TYPE}" in
        sqlite)
            # SQLite DSN：数据文件路径
            dsn="${DEFAULT_DATA_PATH}/data.db"
            ;;
        mysql)
            # MySQL DSN格式：user:pass@tcp(host:port)/dbname?charset=utf8mb4&parseTime=True&loc=Local
            local user="${DATABASE_USERNAME:-root}"
            local pass="${DATABASE_PASSWORD:+"${DATABASE_PASSWORD}"}"
            local host="${DATABASE_HOST:-127.0.0.1}"
            local port="${DATABASE_PORT:-3306}"
            local dbname="${DATABASE_NAME:-pan-index}"
            # 处理空密码（无密码时省略:pass部分）
            if [ -z "${pass}" ]; then
                dsn="${user}@tcp(${host}:${port})/${dbname}?charset=utf8mb4&parseTime=True&loc=Local"
            else
                dsn="${user}:${pass}@tcp(${host}:${port})/${dbname}?charset=utf8mb4&parseTime=True&loc=Local"
            fi
            ;;
    esac
    echo "${dsn}"
}

# 写入配置到config.json（核心函数，完全匹配PanIndex解析要求）
write_config_to_json() {
    validate_db_type  # 先校验数据库类型
    init_config_file  # 确保配置文件存在

    # 构建核心配置参数
    local bind_host="${DEFAULT_BIND_HOST}"
    local app_port="${APP_PORT:-5238}"
    local log_level="${DEFAULT_LOG_LEVEL}"
    local data_path="${DEFAULT_DATA_PATH}"
    local db_type="${DATABASE_TYPE}"
    local db_dsn=$(build_db_dsn)  # 生成对应数据库的DSN
    local ssl_cert="${SSL_CERT_FILE}"
    local ssl_key="${SSL_KEY_FILE}"
    local ui_dir="${CUSTOM_UI_DIR}"

    log_msg "开始写入配置到 ${CFG_FILE}"
    log_msg "核心配置：绑定主机=${bind_host}，端口=${app_port}，数据库类型=${db_type}，DSN=${db_dsn}"

    # 使用jq写入完整配置（严格匹配PanIndex参数名）
    jq --arg bind_host "${bind_host}" \
       --arg port "${app_port}" \
       --arg log_level "${log_level}" \
       --arg data_path "${data_path}" \
       --arg db_type "${db_type}" \
       --arg dsn "${db_dsn}" \
       --arg cert_file "${ssl_cert}" \
       --arg key_file "${ssl_key}" \
       --arg ui_dir "${ui_dir}" \
       '
       .host = $bind_host |
       .port = ($port | tonumber) |
       .log_level = $log_level |
       .data_path = $data_path |
       .db_type = $db_type |
       .dsn = $dsn |
       (if $cert_file != "" and $key_file != "" then .cert_file = $cert_file else del(.cert_file) end) |
       (if $cert_file != "" and $key_file != "" then .key_file = $key_file else del(.key_file) end) |
       (if $ui_dir != "" then .ui = $ui_dir else del(.ui) end)
       ' "${CFG_FILE}" > "${CFG_FILE}.tmp" && mv "${CFG_FILE}.tmp" "${CFG_FILE}"

    # 校验配置写入结果
    if [ $? -eq 0 ]; then
        log_msg "配置文件写入成功"
    else
        log_msg "错误：配置文件写入失败"
        exit 1
    fi

    # 验证配置文件格式是否正确
    if jq . "${CFG_FILE}" >/dev/null 2>&1; then
        log_msg "配置文件格式验证通过：${CFG_FILE}"
    else
        log_msg "错误：配置文件格式异常，启动失败"
        exit 1
    fi

    # 输出最终配置（便于调试）
    log_msg "最终配置内容："
    cat "${CFG_FILE}" >> "${LOG_FILE}"
}

start_process() {
    if status; then
        log_msg "进程已在运行，无需重复启动"
        return 0
    fi

    # 启动前核心步骤：写入配置
    write_config_to_json

    log_msg "正在启动进程..."
    # 执行启动命令（仅指定配置文件，所有参数从JSON读取）
    bash -c "${CMD}" >> ${LOG_FILE} 2>&1 &
    # 写入PID文件
    printf "%s" "$!" > ${PID_FILE}
    log_msg "进程启动成功，PID：$!"
    log_msg "启动命令：${CMD}"
    return 0
}

stop_process() {
    log_msg "正在停止进程..."

    if [ -r "${PID_FILE}" ]; then
        pid=$(head -n 1 "${PID_FILE}" | tr -d '[:space:]')
        
        log_msg "待停止进程 PID：${pid}"
        if ! check_process "${pid}"; then
            log_msg "进程不存在，删除无效 PID 文件"
            rm -f "${PID_FILE}"
            return 0
        fi

        log_msg "向 PID:${pid} 发送 TERM 信号（优雅停止）..."
        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 "等待进程终止...（${count}秒/10秒）"
        done

        if check_process "${pid}"; then
            log_msg "向 PID:${pid} 发送 KILL 信号（强制终止）..."
            kill -KILL "${pid}"
            sleep 1
            rm -f "${PID_FILE}"
            log_msg "进程已强制终止"
        else
            log_msg "进程已正常终止"
            rm -f "${PID_FILE}"
        fi
    else
        log_msg "PID 文件不存在，无运行中的进程"
    fi

    return 0
}

check_process() {
    local pid=$1
    # 检查进程是否存在（kill -0 仅校验不发送信号）
    if kill -0 "${pid}" 2>/dev/null; then
        return 0  # 进程存在
    else
        return 1  # 进程不存在
    fi
}

status() {
    if [ -f "${PID_FILE}" ]; then
        pid=$(head -n 1 "${PID_FILE}" | tr -d '[:space:]')
        if check_process "${pid}"; then
            return 0  # 进程运行中
        else
            log_msg "PID 文件存在但进程未运行，清理无效文件"
            rm -f "${PID_FILE}"
        fi    
    fi
    return 1  # 进程未运行
}

# 命令参数解析
case $1 in
start)
    start_process
    ;;
stop)
    stop_process
    ;;
status)
    if status; then 
        echo "进程正在运行"
        exit 0
    else 
        echo "进程未运行"
        exit 3
    fi
    ;;
*)
    echo "用法：$0 {start|stop|status}"
    exit 1
    ;;
esac