#!/usr/bin/env bash
# ═══════════════════════════════════════════════════════════
#  FutureOSS 智能启动脚本 - Linux
#  自动检测环境 / 安装依赖 / 进度显示 / 守护重启
# ═══════════════════════════════════════════════════════════

PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)"
cd "$PROJECT_DIR"

# ── 颜色 ──
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
BLUE='\033[1;34m'
WHITE='\033[1;37m'
BOLD='\033[1m'
NC='\033[0m'

# ── 工具函数 ──
info()  { echo -e "${CYAN}[信息]${NC} $1"; }
ok()    { echo -e "${GREEN}[成功]${NC} $1"; }
warn()  { echo -e "${YELLOW}[警告]${NC} $1"; }
err()   { echo -e "${RED}[错误]${NC} $1"; }
step()  { echo -e "\n${BOLD}${BLUE}▶ $1${NC}"; }

# 进度条
progress_bar() {
    local current=$1
    local total=$2
    local label=$3
    local pct=$((current * 100 / total))
    local filled=$((pct / 2))
    local empty=$((50 - filled))
    local bar=""
    for ((i=0; i<filled; i++)); do bar+="█"; done
    for ((i=0; i<empty; i++)); do bar+="░"; done
    echo -ne "\r  ${GREEN}[${bar}]${NC} ${WHITE}${pct}%${NC} - ${label}"
}

# ── Logo ──
echo -e "${BOLD}${CYAN}"
echo " ███████╗ ██████╗  ██████╗  ██████╗ ██████╗  ██████╗ "
echo " ██╔════╝ ██╔══██╗ ██╔══██╗ ██╔══██╗ ██╔══██╗██╔════╝ "
echo " █████╗   ██████╔╝ ██████╔╝ ██████╔╝ ██║  ██║██║  ███╗"
echo " ██╔══╝   ██╔══██╗ ██╔══██╗ ██╔══██╗ ██║  ██║██║   ██║"
echo " ██║      ██║  ██║ ██║  ██║ ██║  ██║ ██████╔╝╚██████╔╝"
echo " ╚═╝      ╚═╝  ╚═╝ ╚═╝  ╚═╝ ╚═╝  ╚═╝ ╚═════╝  ╚═════╝ "
echo -e "${NC}"
echo -e "${WHITE}         开发者通用工具套组 · 一切皆为插件${NC}"
echo -e "${WHITE}         https://gitee.com/starlight-apk/feature-oss${NC}"
echo ""

# ── 守护模式 ──
DAEMON=false
if [[ "$1" == "--daemon" || "$1" == "-d" ]]; then
    DAEMON=true
fi

# ═══════════════════════════════════════════════════════════
#  1. 检测操作系统
# ═══════════════════════════════════════════════════════════
step "环境检测"

PKG_MANAGER=""
OS_NAME=""

if [[ -f /etc/os-release ]]; then
    OS_NAME=$(. /etc/os-release && echo "$PRETTY_NAME")
    info "操作系统: $OS_NAME"
fi

if command -v apt-get &>/dev/null; then
    PKG_MANAGER="apt"
    ok "包管理器: apt (Debian/Ubuntu)"
elif command -v yum &>/dev/null; then
    PKG_MANAGER="yum"
    ok "包管理器: yum (CentOS/RHEL)"
elif command -v dnf &>/dev/null; then
    PKG_MANAGER="dnf"
    ok "包管理器: dnf (Fedora)"
elif command -v pacman &>/dev/null; then
    PKG_MANAGER="pacman"
    ok "包管理器: pacman (Arch Linux)"
elif command -v apk &>/dev/null; then
    PKG_MANAGER="apk"
    ok "包管理器: apk (Alpine)"
else
    warn "未检测到已知包管理器，将尝试使用系统自带工具"
fi

install_pkg() {
    local pkg=$1
    case $PKG_MANAGER in
        apt)   sudo apt-get install -y -qq "$pkg" 2>/dev/null ;;
        yum)   sudo yum install -y -q "$pkg" 2>/dev/null ;;
        dnf)   sudo dnf install -y -q "$pkg" 2>/dev/null ;;
        pacman) sudo pacman -S --noconfirm "$pkg" 2>/dev/null ;;
        apk)   sudo apk add --quiet "$pkg" 2>/dev/null ;;
        *)     warn "无法自动安装 $pkg" ; return 1 ;;
    esac
}

update_pkg_cache() {
    case $PKG_MANAGER in
        apt)   sudo apt-get update -qq 2>/dev/null ;;
        yum)   sudo yum makecache -q 2>/dev/null ;;
        dnf)   sudo dnf makecache -q 2>/dev/null ;;
        pacman) sudo pacman -Sy --quiet 2>/dev/null ;;
        apk)   sudo apk update --quiet 2>/dev/null ;;
    esac
}

TOTAL_STEPS=6
CURRENT_STEP=0

# ═══════════════════════════════════════════════════════════
#  2. 安装系统依赖
# ═══════════════════════════════════════════════════════════
step "安装系统依赖"

# 系统命令依赖和PHP扩展分开处理
CMD_DEPENDENCIES=("git" "curl" "wget" "php" "python3")
PHP_EXTENSIONS=("php-cli" "php-mbstring" "php-xml" "php-zip")
PYTHON_PKGS=("pip" "venv")

DEPENDENCIES=(${CMD_DEPENDENCIES[@]} ${PHP_EXTENSIONS[@]} "python3-pip" "python3-venv")
DEP_TOTAL=${#DEPENDENCIES[@]}
DEP_INSTALLED=0

for dep in "${DEPENDENCIES[@]}"; do
    DEP_INSTALLED=$((DEP_INSTALLED + 1))
    progress_bar $DEP_INSTALLED $DEP_TOTAL "检测 $dep"

    # PHP扩展包不通过command检测，跳过
    if [[ "$dep" == php-* ]]; then
        continue
    fi
    # python3-venv也不通过command检测
    if [[ "$dep" == "python3-venv" || "$dep" == "python3-pip" ]]; then
        continue
    fi

    if command -v "$dep" &>/dev/null; then
        continue
    fi

    # 尝试安装
    if ! install_pkg "$dep" 2>/dev/null; then
        # 更新缓存后重试
        update_pkg_cache 2>/dev/null
        install_pkg "$dep" 2>/dev/null || true
    fi

    if command -v "$dep" &>/dev/null; then
        continue
    fi
done

echo -e "\n"

# 验证关键依赖
if command -v php &>/dev/null; then
    ok "PHP: $(php --version 2>&1 | head -n 1)"
else
    warn "PHP 未安装，WebUI 可能无法正常工作"
fi

if command -v python3 &>/dev/null; then
    ok "Python: $(python3 --version 2>&1)"
else
    err "Python3 未安装，无法继续"
    exit 1
fi

# ═══════════════════════════════════════════════════════════
#  3. Python 虚拟环境
# ═══════════════════════════════════════════════════════════
step "配置 Python 环境"

PYTHON_CMD="python3"
VENV_DIR=".venv"

if [[ ! -d "$VENV_DIR" ]]; then
    info "创建虚拟环境..."
    $PYTHON_CMD -m venv "$VENV_DIR" 2>/dev/null || {
        warn "venv 模块缺失，尝试安装..."
        case $PKG_MANAGER in
            apt)   install_pkg "python3-venv" ;;
            yum)   install_pkg "python3-virtualenv" ;;
            dnf)   install_pkg "python3-virtualenv" ;;
            pacman) ;;
            apk)   install_pkg "py3-virtualenv" ;;
        esac
        $PYTHON_CMD -m venv "$VENV_DIR" 2>/dev/null || {
            err "无法创建虚拟环境"
            exit 1
        }
    }
    ok "虚拟环境已创建"
else
    ok "虚拟环境已存在"
fi

source "$VENV_DIR/bin/activate"
PIP_CMD="$VENV_DIR/bin/pip"

# ═══════════════════════════════════════════════════════════
#  检测虚拟环境依赖完整性
# ═══════════════════════════════════════════════════════════
info "检测虚拟环境依赖完整性..."

VENV_INCOMPLETE=false
MISSING_VENV_DEPS=()

for pkg in "${CORE_DEPS[@]}"; do
    import_name="${PKG_IMPORT_MAP[$pkg]}"
    if ! $PYTHON_CMD -c "import $import_name" 2>/dev/null; then
        VENV_INCOMPLETE=true
        MISSING_VENV_DEPS+=("$pkg")
    fi
done

# 同时检测 requirements.txt 中的依赖
if [[ -f "requirements.txt" ]]; then
    while IFS= read -r line || [[ -n "$line" ]]; do
        # 跳过空行和注释
        [[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue
        # 提取包名（去除版本号）
        pkg_name=$(echo "$line" | sed -E 's/([a-zA-Z0-9_-]+).*/\1/')
        [[ -z "$pkg_name" ]] && continue
        # 尝试导入（将连字符替换为下划线）
        import_name="${pkg_name//-/_}"
        if ! $PYTHON_CMD -c "import $import_name" 2>/dev/null; then
            # 不在核心依赖列表中的才添加
            if [[ ! " ${CORE_DEPS[@]} " =~ " ${pkg_name} " ]]; then
                VENV_INCOMPLETE=true
                MISSING_VENV_DEPS+=("$pkg_name")
            fi
        fi
    done < "requirements.txt"
fi

if $VENV_INCOMPLETE; then
    warn "虚拟环境依赖不完整，缺失: ${MISSING_VENV_DEPS[*]}"
    info "正在安装缺失的依赖..."
    for pkg in "${MISSING_VENV_DEPS[@]}"; do
        $PIP_CMD install "$pkg" -q 2>/dev/null || \
        $PIP_CMD install "$pkg" --break-system-packages -q 2>/dev/null || \
        warn "无法安装 $pkg"
    done
else
    ok "虚拟环境依赖完整"
fi

# ═══════════════════════════════════════════════════════════
#  4. 安装 Python 依赖
# ═══════════════════════════════════════════════════════════
step "安装 Python 依赖"

# 包名到导入名的映射
declare -A PKG_IMPORT_MAP=(
    ["click"]="click"
    ["pyyaml"]="yaml"
    ["websockets"]="websockets"
    ["psutil"]="psutil"
    ["cryptography"]="cryptography"
)

CORE_DEPS=("click" "pyyaml" "websockets" "psutil" "cryptography")
DEP_COUNT=${#CORE_DEPS[@]}
DEP_CURRENT=0

for pkg in "${CORE_DEPS[@]}"; do
    DEP_CURRENT=$((DEP_CURRENT + 1))
    progress_bar $DEP_CURRENT $DEP_COUNT "安装 $pkg"

    # 使用正确的导入名检测
    import_name="${PKG_IMPORT_MAP[$pkg]}"
    $PYTHON_CMD -c "import $import_name" 2>/dev/null && continue

    $PIP_CMD install "$pkg" -q 2>/dev/null || \
    $PIP_CMD install "$pkg" --break-system-packages -q 2>/dev/null || true
done

echo -e "\n"

# 安装项目依赖
if [[ -f "pyproject.toml" ]]; then
    info "安装项目配置依赖..."
    $PIP_CMD install -e . -q 2>/dev/null || true
fi

if [[ -f "requirements.txt" ]]; then
    info "安装 requirements.txt..."
    $PIP_CMD install -r requirements.txt -q 2>/dev/null || true
fi

ok "Python 依赖安装完成"

# ═══════════════════════════════════════════════════════════
#  5. 创建数据目录
# ═══════════════════════════════════════════════════════════
step "初始化数据目录"

DATA_DIRS=("data" "data/html-render" "data/web-toolkit" "data/plugin-storage" "data/DCIM" "data/signature-verifier/keys/private" "data/signature-verifier/keys/public" "logs")
DIR_COUNT=${#DATA_DIRS[@]}
DIR_CURRENT=0

for dir in "${DATA_DIRS[@]}"; do
    DIR_CURRENT=$((DIR_CURRENT + 1))
    progress_bar $DIR_CURRENT $DIR_COUNT "创建 $dir"
    mkdir -p "$dir"
done

echo -e "\n"
ok "数据目录已就绪"

# ═══════════════════════════════════════════════════════════
#  6. 检查 MySQL (可选)
# ═══════════════════════════════════════════════════════════
step "检查数据库 (可选)"

if command -v mysql &>/dev/null; then
    ok "MySQL: $(mysql --version 2>&1)"
    if pgrep mysqld > /dev/null 2>&1 || pgrep mariadbd > /dev/null 2>&1; then
        ok "MySQL 服务运行中"
        mysql -u root -e "CREATE DATABASE IF NOT EXISTS futureoss CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" 2>/dev/null && \
            ok "数据库 futureoss 已就绪" || \
            warn "无法创建数据库，请检查权限"
    else
        warn "MySQL 服务未运行"
        info "启动命令: sudo systemctl start mysql (或 mariadb)"
    fi
else
    info "MySQL 未安装 (可选功能)"
    info "安装: sudo apt install mysql-server (Debian/Ubuntu)"
    info "      sudo yum install mysql-server (CentOS/RHEL)"
fi

# ═══════════════════════════════════════════════════════════
#  7. 启动服务
# ═══════════════════════════════════════════════════════════
step "启动 FutureOSS"

if $DAEMON; then
    LOG_FILE="logs/futureoss.log"
    PID_FILE="logs/futureoss.pid"

    if [[ -f "$PID_FILE" ]]; then
        OLD_PID=$(cat "$PID_FILE")
        if kill -0 "$OLD_PID" 2>/dev/null; then
            warn "已有进程运行 (PID: $OLD_PID)"
            info "停止: kill $OLD_PID 或 bash start.sh stop"
            exit 0
        fi
    fi

    nohup $PYTHON_CMD -m oss.cli serve > "$LOG_FILE" 2>&1 &
    NEW_PID=$!
    echo "$NEW_PID" > "$PID_FILE"
    ok "守护进程已启动 (PID: $NEW_PID)"
    info "日志文件: $LOG_FILE"
    sleep 2
    curl -s http://localhost:8080/health &>/dev/null && ok "服务就绪: http://localhost:8080" || warn "服务启动中，请稍候..."
    exit 0
fi

# 前台模式 + 崩溃自动重启
echo -e "${WHITE}运行中... 按 Ctrl+C 停止${NC}"
echo ""

RESTART_DELAY=3
RESTART_COUNT=0

while true; do
    $PYTHON_CMD -m oss.cli serve
    EXIT_CODE=$?

    if [[ $EXIT_CODE -eq 0 ]]; then
        ok "服务正常退出"
        break
    fi

    RESTART_COUNT=$((RESTART_COUNT + 1))
    warn "服务异常退出 (code: $EXIT_CODE)，${RESTART_DELAY}s 后重启... (第 $RESTART_COUNT 次)"
    sleep $RESTART_DELAY

    # 指数退避
    if [[ $RESTART_DELAY -lt 30 ]]; then
        RESTART_DELAY=$((RESTART_DELAY * 2))
    fi
done

deactivate 2>/dev/null || true
