#!/bin/bash

# 知识库系统部署脚本
# 使用Laravel Octane + Swoole

set -e  # 遇到错误立即退出

# 配置变量
SERVER_HOST="192.168.1.33"
SERVER_USER="root"
SERVER_PASSWORD="Sipai@123"
SERVER_PATH="/opt/KnowledgeBase"
IMAGE_NAME="knowledge-base-app"
IMAGE_TAG="latest"
COMPOSE_VERSION="1.25.5"

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 检查必要工具
check_requirements() {
    log_info "检查部署环境..."
    
    if ! command -v docker &> /dev/null; then
        log_error "Docker 未安装"
        exit 1
    fi
    
    if ! command -v sshpass &> /dev/null; then
        log_error "sshpass 未安装，请先安装: brew install sshpass"
        exit 1
    fi
    
    log_info "环境检查完成"
}

# 设置网络代理（如果需要）
setup_proxy() {
    if [ "$USE_PROXY" = "true" ]; then
        log_info "设置网络代理..."
        export https_proxy=http://127.0.0.1:7890
        export http_proxy=http://127.0.0.1:7890
        export all_proxy=socks5://127.0.0.1:7890
        log_info "代理设置完成"
    fi
}

# 清理本地构建文件
clean_local() {
    log_info "清理本地构建文件..."
    
    # 清理不需要的文件
    rm -rf node_modules/.cache
    rm -rf storage/logs/*.log
    rm -rf storage/framework/cache/data/*
    rm -rf storage/framework/sessions/*
    rm -rf storage/framework/views/*
    
    log_info "本地清理完成"
}

# 构建Docker镜像
build_image() {
    log_info "开始构建Docker镜像..."
    
    # 构建镜像
    docker build --platform linux/amd64 -t ${IMAGE_NAME}:${IMAGE_TAG} .
    
    if [ $? -eq 0 ]; then
        log_info "Docker镜像构建成功"
    else
        log_error "Docker镜像构建失败"
        exit 1
    fi
}

# 导出镜像为tar包
export_image() {
    log_info "导出Docker镜像..."
    
    docker save ${IMAGE_NAME}:${IMAGE_TAG} | gzip > ${IMAGE_NAME}-${IMAGE_TAG}.tar.gz
    
    if [ $? -eq 0 ]; then
        log_info "镜像导出成功: ${IMAGE_NAME}-${IMAGE_TAG}.tar.gz"
    else
        log_error "镜像导出失败"
        exit 1
    fi
}

# 同步代码到服务器
sync_code() {
    log_info "同步代码到服务器..."
    
    # 创建临时目录用于同步
    TEMP_DIR=$(mktemp -d)
    
    # 复制需要的文件
    cp -r . "$TEMP_DIR/"
    
    # 删除不需要的文件
    cd "$TEMP_DIR"
    rm -rf node_modules
    # 保留vendor目录，因为服务器上缺少Octane包
    rm -rf storage/logs/*.log
    rm -rf storage/framework/cache/data/*
    rm -rf storage/framework/sessions/*
    rm -rf storage/framework/views/*
    rm -rf .git
    rm -rf tests
    rm -rf docs
    rm -rf .DS_Store
    rm -rf *.tar.gz
    
    # 同步到服务器
    sshpass -p "${SERVER_PASSWORD}" rsync -avz --delete \
        --exclude='storage/mysql/' \
        --exclude='storage/redis/' \
        --exclude='storage/meilisearch/' \
        --exclude='storage/app/documents/' \
        --exclude='storage/app/markdown/' \
        "$TEMP_DIR/" "${SERVER_USER}@${SERVER_HOST}:${SERVER_PATH}/"
    
    # 清理临时目录
    rm -rf "$TEMP_DIR"
    
    log_info "代码同步完成"
}

# 上传Docker镜像
upload_image() {
    log_info "上传Docker镜像到服务器..."
    
    sshpass -p "${SERVER_PASSWORD}" scp ${IMAGE_NAME}-${IMAGE_TAG}.tar.gz \
        ${SERVER_USER}@${SERVER_HOST}:${SERVER_PATH}/
    
    log_info "镜像上传完成"
}

# 在服务器上部署
deploy_on_server() {
    log_info "在服务器上执行部署..."
    
    sshpass -p "${SERVER_PASSWORD}" ssh ${SERVER_USER}@${SERVER_HOST} << EOF
        cd ${SERVER_PATH}
        
        # 停止现有服务
        echo "停止现有服务..."
        docker-compose -f docker-compose-simple.yml down || true
        
        # 删除旧镜像
        echo "清理旧镜像..."
        docker rmi ${IMAGE_NAME}:${IMAGE_TAG} || true
        docker system prune -f
        
        # 加载新镜像
        echo "加载新镜像..."
        docker load < ${IMAGE_NAME}-${IMAGE_TAG}.tar.gz
        
        # 删除镜像文件
        rm -f ${IMAGE_NAME}-${IMAGE_TAG}.tar.gz
        
        # 复制生产环境配置
        echo "设置生产环境配置..."
        cp .env.production .env
        
        # 生成新的APP_KEY（如果需要）
        if grep -q "your-app-key-here" .env; then
            echo "生成新的APP_KEY..."
            APP_KEY=\$(openssl rand -base64 32)
            sed -i "s|your-app-key-here-change-this-in-production|base64:\$APP_KEY|g" .env
        fi
        
        # 生成新的MEILISEARCH_KEY（如果需要）
        if grep -q "your-master-key-change-this-in-production" .env; then
            echo "生成新的MEILISEARCH_KEY..."
            MEILI_KEY=\$(openssl rand -hex 32)
            sed -i "s|your-master-key-change-this-in-production|\$MEILI_KEY|g" .env
        fi
        
        # 启动服务
        echo "启动服务..."
        docker-compose -f docker-compose-simple.yml up -d
        
        # 等待服务启动
        echo "等待服务启动..."
        sleep 30
        
        # 运行数据库迁移
        echo "运行数据库迁移..."
        docker-compose -f docker-compose-simple.yml exec -T app php artisan migrate --force
        
        # 清理缓存
        echo "清理应用缓存..."
        docker-compose -f docker-compose-simple.yml exec -T app php artisan config:clear
        docker-compose -f docker-compose-simple.yml exec -T app php artisan cache:clear
        docker-compose -f docker-compose-simple.yml exec -T app php artisan route:clear
        docker-compose -f docker-compose-simple.yml exec -T app php artisan view:clear
        
        # 重新生成缓存
        echo "重新生成缓存..."
        docker-compose -f docker-compose-simple.yml exec -T app php artisan config:cache
        docker-compose -f docker-compose-simple.yml exec -T app php artisan route:cache
        docker-compose -f docker-compose-simple.yml exec -T app php artisan view:cache
        
        # 创建搜索索引
        echo "创建搜索索引..."
        docker-compose -f docker-compose-simple.yml exec -T app php artisan scout:import || true
        
        echo "部署完成！"
EOF
    
    log_info "服务器部署完成"
}

# 验证部署
verify_deployment() {
    log_info "验证部署状态..."
    
    sshpass -p "${SERVER_PASSWORD}" ssh ${SERVER_USER}@${SERVER_HOST} << EOF
        cd ${SERVER_PATH}
        
        echo "=== 服务状态 ==="
        docker-compose -f docker-compose-simple.yml ps
        
        echo "=== 应用健康检查 ==="
        curl -f http://localhost:8000/health || echo "健康检查失败"
        
        echo "=== 队列状态 ==="
        docker-compose -f docker-compose-simple.yml exec -T app php artisan queue:work --once --timeout=10 || echo "队列测试失败"
        
        echo "=== Meilisearch状态 ==="
        curl -f http://localhost:7700/health || echo "Meilisearch连接失败"
        
        echo "=== 数据库连接 ==="
        docker-compose -f docker-compose-simple.yml exec -T app php artisan tinker --execute="DB::connection()->getPdo(); echo 'Database connected successfully';" || echo "数据库连接失败"
EOF
    
    log_info "部署验证完成"
}

# 清理本地文件
cleanup() {
    log_info "清理本地文件..."
    rm -f ${IMAGE_NAME}-${IMAGE_TAG}.tar.gz
    log_info "清理完成"
}

# 主函数
main() {
    log_info "开始部署知识库系统..."
    
    check_requirements
    setup_proxy
    clean_local
    build_image
    export_image
    sync_code
    upload_image
    deploy_on_server
    verify_deployment
    cleanup
    
    log_info "部署流程全部完成！"
    log_info "访问地址: http://${SERVER_HOST}:8000"
}

# 执行主函数
main "$@"