#!/bin/bash
# ============================================
# 中华药典 AI Agent — Java 后端部署脚本
# 用法: ./java-deploy.sh {start|stop|restart|status|logs|build|deploy|rollback}
# ============================================

set -e

APP_DIR="/opt/pharmacopoeia-ai/backend-java"
PROJECT_DIR="/opt/pharmacopoeia-ai"
JAR_FILE="$APP_DIR/target/pharmacopoeia-ai-1.0.0.jar"
LOG_DIR="/var/log/pharmacopoeia"
PID_FILE="$APP_DIR/app.pid"

# 加载 .env 环境变量
load_env() {
    if [ -f "$PROJECT_DIR/.env" ]; then
        set -a
        source "$PROJECT_DIR/.env"
        set +a
    fi
}
load_env

mkdir -p "$LOG_DIR"

# ---- 服务端口 ----
PORT=${SERVER_PORT:-9000}
HEALTH_URL="http://localhost:${PORT}/health"

# ============================================
# 通用函数
# ============================================

running() {
    [ -f "$PID_FILE" ] && kill -0 "$(cat "$PID_FILE")" 2>/dev/null
}

get_pid() {
    cat "$PID_FILE" 2>/dev/null || echo "N/A"
}

health_check() {
    curl -sf "$HEALTH_URL" > /dev/null 2>&1
}

# ============================================
# 启动
# ============================================

start() {
    if running; then
        echo "⚠️  后端已在运行中 (PID: $(get_pid))"
        curl -sf "$HEALTH_URL" | python3 -m json.tool 2>/dev/null || true
        return 0
    fi

    # 自动编译（如果 JAR 不存在）
    if [ ! -f "$JAR_FILE" ]; then
        echo "📦 JAR 不存在，正在编译..."
        cd "$APP_DIR"
        mvn clean package -DskipTests -q
        echo "✅ 编译完成"
    fi

    echo "🚀 启动后端..."
    cd "$APP_DIR"

    JVM_OPTS="-Xms512m -Xmx2g"
    JVM_OPTS="$JVM_OPTS -XX:+UseG1GC"
    JVM_OPTS="$JVM_OPTS -Dfile.encoding=UTF-8"
    JVM_OPTS="$JVM_OPTS -Djava.security.egd=file:/dev/./urandom"

    nohup java $JVM_OPTS -jar "$JAR_FILE" \
        --server.port="$PORT" \
        >> "$LOG_DIR/backend.log" 2>&1 &

    echo $! > "$PID_FILE"
    echo "   PID: $(get_pid)"

    # 等启动完成
    echo -n "   等待启动"
    for i in $(seq 1 30); do
        if health_check 2>/dev/null; then
            echo ""
            echo "✅ 启动成功！"
            curl -sf "$HEALTH_URL" | python3 -m json.tool 2>/dev/null || true
            return 0
        fi
        echo -n "."
        sleep 1
    done

    echo ""
    echo "❌ 启动超时，查看日志:"
    tail -30 "$LOG_DIR/backend.log"
    rm -f "$PID_FILE"
    return 1
}

# ============================================
# 停止
# ============================================

stop() {
    if ! running; then
        echo "后端未运行"
        rm -f "$PID_FILE"
        return 0
    fi

    PID=$(get_pid)
    echo "🛑 停止后端 (PID: $PID)..."
    kill "$PID"

    for i in $(seq 1 30); do
        if ! kill -0 "$PID" 2>/dev/null; then
            echo "✅ 已停止"
            rm -f "$PID_FILE"
            return 0
        fi
        sleep 1
    done

    echo "⚠️  超时，强制终止..."
    kill -9 "$PID" 2>/dev/null || true
    rm -f "$PID_FILE"
    echo "✅ 已强制停止"
}

# ============================================
# 重启
# ============================================

restart() {
    echo "⏳ 重启后端..."
    stop
    sleep 2
    start
}

# ============================================
# 状态
# ============================================

status() {
    echo "========================================"
    echo "  中华药典 AI — Java 后端"
    echo "========================================"

    if running; then
        echo "  状态: ✅ 运行中"
        echo "  PID:  $(get_pid)"
        echo "  端口: $PORT"
        echo ""
        curl -sf "$HEALTH_URL" | python3 -m json.tool 2>/dev/null || echo "  (健康检查无响应)"
    else
        echo "  状态: ❌ 未运行"
    fi

    echo ""
    echo "  日志: $LOG_DIR/backend.log"
    echo "========================================"
}

# ============================================
# 日志

# ============================================

logs() {
    if [ "$1" = "-f" ]; then
        tail -f "$LOG_DIR/backend.log"
    else
        echo "=== 最近 100 行日志 ==="
        tail -${1:-100} "$LOG_DIR/backend.log"
    fi
}

# ============================================
# 编译
# ============================================

build() {
    echo "📦 拉取最新代码..."
    cd "$PROJECT_DIR"
    git pull

    echo "🔨 编译打包..."
    cd "$APP_DIR"
    mvn clean package -DskipTests -q

    if [ -f "$JAR_FILE" ]; then
        echo "✅ 编译成功: $JAR_FILE"
        ls -lh "$JAR_FILE"
    else
        echo "❌ 编译失败"
        return 1
    fi
}

# ============================================
# 一键部署（拉代码 → 编译 → 备份 → 重启）
# ============================================

deploy() {
    echo "========================================"
    echo "  一键部署"
    echo "========================================"

    echo ""
    echo "📥 拉取代码..."
    cd "$PROJECT_DIR"
    git pull

    echo ""
    echo "🔨 编译打包..."
    cd "$APP_DIR"
    mvn clean package -DskipTests -q

    if [ ! -f "$JAR_FILE" ]; then
        echo "❌ 编译失败，取消部署"
        return 1
    fi

    echo "✅ 编译完成: $(ls -lh "$JAR_FILE" | awk '{print $5}')"

    # 备份当前 JAR
    BACKUP_DIR="$APP_DIR/backups"
    mkdir -p "$BACKUP_DIR"
    if [ -f "$JAR_FILE" ]; then
        BACKUP_FILE="$BACKUP_DIR/pharmacopoeia-ai-$(date +%Y%m%d-%H%M%S).jar"
        cp "$JAR_FILE" "$BACKUP_FILE"
        echo "📦 已备份: $BACKUP_FILE"

        # 保留最近 5 个备份
        ls -t "$BACKUP_DIR"/*.jar 2>/dev/null | tail -n +6 | xargs rm -f 2>/dev/null || true
    fi

    echo ""
    restart
}

# ============================================
# 回滚
# ============================================

rollback() {
    BACKUP_DIR="$APP_DIR/backups"

    if [ ! -d "$BACKUP_DIR" ] || [ -z "$(ls -A "$BACKUP_DIR" 2>/dev/null)" ]; then
        echo "❌ 没有可用的备份"
        return 1
    fi

    echo "可用备份:"
    ls -lht "$BACKUP_DIR"/*.jar 2>/dev/null | head -10

    echo ""
    if [ -n "$1" ]; then
        ROLLBACK_FILE="$1"
    else
        ROLLBACK_FILE=$(ls -t "$BACKUP_DIR"/*.jar 2>/dev/null | head -1)
        echo "回滚到最新备份: $(basename "$ROLLBACK_FILE")"
    fi

    if [ ! -f "$ROLLBACK_FILE" ]; then
        echo "❌ 备份文件不存在: $ROLLBACK_FILE"
        return 1
    fi

    echo ""
    echo "⏪ 回滚..."
    cp "$ROLLBACK_FILE" "$JAR_FILE"
    echo "✅ 已替换为: $(basename "$ROLLBACK_FILE")"
    restart
}

# ============================================
# 入口
# ============================================

case "${1:-start}" in
    start)    start ;;
    stop)     stop ;;
    restart)  restart ;;
    status)   status ;;
    logs)     logs "${2:-100}" ;;
    logf)     logs -f ;;
    build)    build ;;
    deploy)   deploy ;;
    rollback) rollback "$2" ;;
    help|--help|-h)
        echo "用法: $0 {start|stop|restart|status|logs|logf|build|deploy|rollback}"
        echo ""
        echo "  start     启动后端"
        echo "  stop      停止后端"
        echo "  restart   重启后端"
        echo "  status    查看状态"
        echo "  logs      查看最近 100 行日志"
        echo "  logf      实时跟踪日志"
        echo "  build     拉代码 + 编译"
        echo "  deploy    拉代码 + 编译 + 备份 + 重启（一键上线）"
        echo "  rollback  回滚到上一个备份（可指定备份文件路径）"
        exit 0
        ;;
    *)
        echo "用法: $0 {start|stop|restart|status|logs|logf|build|deploy|rollback}"
        exit 1
        ;;
esac
