#!/bin/bash

# 云盘应用 Docker 构建和部署脚本
# 用于构建生产环境的 Docker 镜像并部署到 Linux 环境

set -e

# 配置变量
APP_NAME="cloud-drive-backend"
IMAGE_NAME="${APP_NAME}:latest"
CONTAINER_NAME="${APP_NAME}"
PORT="8002"
USE_SUDO=false

# Docker命令包装函数
docker_cmd() {
    if [ "$USE_SUDO" = true ]; then
        sudo docker "$@"
    else
        docker "$@"
    fi
}

# Docker Compose命令包装函数
docker_compose_cmd() {
    if [ "$USE_SUDO" = true ]; then
        sudo docker-compose "$@"
    else
        docker-compose "$@"
    fi
}

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

# 日志函数
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

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

# 检查 Docker 是否安装
check_docker() {
    if ! command -v docker &> /dev/null; then
        log_error "Docker 未安装，请先安装 Docker"
        exit 1
    fi

    # 检查Docker权限
    if ! docker info &> /dev/null; then
        log_warning "Docker权限不足，尝试修复..."

        # 检查当前用户是否在docker组中
        if ! groups $(whoami) | grep -q docker; then
            log_warning "当前用户不在docker组中"

            # 尝试将用户添加到docker组
            if command -v sudo &> /dev/null; then
                log_info "尝试将用户添加到docker组（需要sudo权限）..."
                sudo usermod -aG docker $(whoami) 2>/dev/null || {
                    log_warning "无法自动添加用户到docker组"
                    log_info "请手动执行: sudo usermod -aG docker $(whoami)"
                    log_info "然后重新登录或执行: newgrp docker"
                }
            else
                log_error "sudo命令不可用，无法修复Docker权限"
            fi
        fi

        # 尝试使用sudo运行docker
        if command -v sudo &> /dev/null && sudo docker info &> /dev/null; then
            log_info "检测到可以使用sudo运行Docker"
            USE_SUDO=true
        else
            log_error "Docker权限不足且无法修复"
            log_info "解决方案:"
            log_info "1. 将用户添加到docker组: sudo usermod -aG docker $(whoami)"
            log_info "2. 重新登录或执行: newgrp docker"
            log_info "3. 或使用sudo运行此脚本"
            exit 1
        fi
    fi

    log_success "Docker 已安装并可访问"
}

# 检查 Docker Compose 是否安装
check_docker_compose() {
    if ! command -v docker-compose &> /dev/null; then
        log_error "Docker Compose 未安装，请先安装 Docker Compose"
        exit 1
    fi
    log_success "Docker Compose 已安装"
}

# 停止并删除现有容器
stop_existing_container() {
    if docker_cmd ps -q -f name=${CONTAINER_NAME} | grep -q .; then
        log_warning "停止现有容器 ${CONTAINER_NAME}"
        docker_cmd stop ${CONTAINER_NAME}
    fi

    if docker_cmd ps -aq -f name=${CONTAINER_NAME} | grep -q .; then
        log_warning "删除现有容器 ${CONTAINER_NAME}"
        docker_cmd rm ${CONTAINER_NAME}
    fi
}

# 构建镜像
build_image() {
    log_info "开始构建 Docker 镜像..."
    docker_cmd build -t ${IMAGE_NAME} .

    if [ $? -eq 0 ]; then
        log_success "镜像构建成功: ${IMAGE_NAME}"
    else
        log_error "镜像构建失败"
        exit 1
    fi
}

# 运行容器
run_container() {
    log_info "启动容器..."

    # 创建必要的目录
    mkdir -p uploads logs

    docker_cmd run -d \
        --name ${CONTAINER_NAME} \
        --restart unless-stopped \
        -p ${PORT}:${PORT} \
        -v $(pwd)/uploads:/app/uploads \
        -v $(pwd)/logs:/app/logs \
        -e ENVIRONMENT=production \
        -e TZ=Asia/Shanghai \
        ${IMAGE_NAME}

    if [ $? -eq 0 ]; then
        log_success "容器启动成功: ${CONTAINER_NAME}"
    else
        log_error "容器启动失败"
        exit 1
    fi
}

# 检查容器状态
check_container() {
    log_info "检查容器状态..."
    sleep 5

    if docker_cmd ps | grep -q ${CONTAINER_NAME}; then
        log_success "容器运行正常"

        # 显示容器日志
        log_info "容器日志:"
        docker_cmd logs ${CONTAINER_NAME}

        # 测试健康检查
        log_info "测试健康检查..."
        sleep 10
        if curl -f http://localhost:${PORT}/api/v1/health &> /dev/null; then
            log_success "健康检查通过！"
        else
            log_warning "健康检查失败，但容器仍在运行"
        fi
    else
        log_error "容器未正常运行"
        log_error "容器日志:"
        docker_cmd logs ${CONTAINER_NAME}
        exit 1
    fi
}

# 使用 Docker Compose 部署
deploy_with_compose() {
    log_info "使用 Docker Compose 部署..."

    # 创建 .env 文件（如果不存在）
    if [ ! -f .env ]; then
        log_warning "创建 .env 文件，请根据实际情况修改配置"
        cat > .env << EOF
# 数据库配置
DATABASE_URL=mysql://username:password@mysql:3306/mytest_db
MYSQL_ROOT_PASSWORD=rootpassword
MYSQL_DATABASE=mytest_db
MYSQL_USER=username
MYSQL_PASSWORD=password

# Redis 配置
REDIS_URL=redis://redis:6379/0

# 应用配置
SECRET_KEY=your-production-secret-key
CORS_ORIGINS=http://localhost:3003,https://yourdomain.com
ENVIRONMENT=production
EOF
        log_warning "请编辑 .env 文件设置正确的配置"
    fi

    docker_compose_cmd down
    docker_compose_cmd up -d --build

    if [ $? -eq 0 ]; then
        log_success "Docker Compose 部署成功"
        log_info "等待服务启动..."
        sleep 15

        if curl -f http://localhost:${PORT}/api/v1/health &> /dev/null; then
            log_success "应用启动成功！"
            log_info "服务地址: http://localhost:${PORT}"
            log_info "API文档: http://localhost:${PORT}/docs"
            log_info "健康检查: http://localhost:${PORT}/api/v1/health"
        else
            log_warning "应用启动可能有问题，请检查日志"
            log_info "查看日志命令: docker-compose logs -f"
            docker_compose_cmd logs --tail=20
        fi
    else
        log_error "Docker Compose 部署失败"
        exit 1
    fi
}

# 清理镜像和容器
cleanup() {
    log_info "清理旧的镜像和容器..."

    # 停止并删除容器
    stop_existing_container

    # 删除镜像
    if docker_cmd images -q ${IMAGE_NAME} | grep -q .; then
        log_warning "删除旧镜像: ${IMAGE_NAME}"
        docker_cmd rmi ${IMAGE_NAME} 2>/dev/null || true
    fi

    # 清理未使用的镜像和容器
    log_info "清理未使用的 Docker 资源..."
    docker_cmd system prune -f

    log_success "清理完成"
}

# 显示帮助信息
show_help() {
    echo "云盘应用 Docker 部署脚本"
    echo ""
    echo "用法: $0 [选项]"
    echo ""
    echo "选项:"
    echo "  build        - 仅构建镜像"
    echo "  run          - 仅运行容器（需要先构建镜像）"
    echo "  compose      - 使用 Docker Compose 部署"
    echo "  stop         - 停止容器"
    echo "  restart      - 重启容器"
    echo "  logs         - 查看容器日志"
    echo "  cleanup      - 清理镜像和容器"
    echo "  status       - 查看容器状态"
    echo "  help         - 显示此帮助信息"
    echo ""
    echo "默认行为: 构建镜像并运行容器"
}

# 主函数
main() {
    case "${1:-}" in
        "build")
            check_docker
            build_image
            ;;
        "run")
            check_docker
            stop_existing_container
            run_container
            check_container
            ;;
        "compose")
            check_docker
            check_docker_compose
            deploy_with_compose
            ;;
        "stop")
            if docker ps -q -f name=${CONTAINER_NAME} | grep -q .; then
                docker stop ${CONTAINER_NAME}
                log_success "容器已停止"
            else
                log_warning "容器未运行"
            fi
            ;;
        "restart")
            if docker ps -q -f name=${CONTAINER_NAME} | grep -q .; then
                docker restart ${CONTAINER_NAME}
                log_success "容器已重启"
                sleep 5
                check_container
            else
                log_warning "容器未运行，尝试启动..."
                check_docker
                stop_existing_container
                run_container
                check_container
            fi
            ;;
        "logs")
            if docker ps -q -f name=${CONTAINER_NAME} | grep -q .; then
                docker logs -f ${CONTAINER_NAME}
            else
                log_warning "容器未运行"
            fi
            ;;
        "cleanup")
            check_docker
            cleanup
            ;;
        "status")
            if docker ps -q -f name=${CONTAINER_NAME} | grep -q .; then
                log_success "容器正在运行"
                docker ps | grep ${CONTAINER_NAME}
            else
                log_warning "容器未运行"
            fi
            ;;
        "help"|"-h"|"--help")
            show_help
            ;;
        "")
            log_info "开始构建和部署云盘应用..."
            check_docker
            stop_existing_container
            build_image
            run_container
            check_container
            log_success "部署完成！应用正在运行中"
            ;;
        *)
            log_error "未知选项: $1"
            show_help
            exit 1
            ;;
    esac
}

# 执行主函数
main "$@"