#!/bin/bash
# 数据库连接诊断脚本
# 用于诊断和修复数据库连接池问题

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

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

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

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

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

# 检查数据库服务状态
check_database_service() {
    log_info "检查数据库服务状态..."
    
    if docker ps --filter "name=anxin-mysql-prod" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep anxin-mysql-prod; then
        log_success "✓ MySQL容器正在运行"
        
        # 检查健康状态
        local health=$(docker inspect anxin-mysql-prod --format='{{.State.Health.Status}}' 2>/dev/null || echo "unknown")
        log_info "MySQL健康状态: $health"
        
        if [[ "$health" == "healthy" ]]; then
            log_success "✓ MySQL容器健康检查通过"
        else
            log_warn "MySQL容器健康检查未通过"
        fi
    else
        log_error "✗ MySQL容器未运行"
        return 1
    fi
}

# 测试数据库连接
test_database_connection() {
    log_info "测试数据库连接..."
    
    if [[ -f "environments/.env.production" ]]; then
        source environments/.env.production
        
        # 测试root连接
        log_info "测试root用户连接..."
        if docker exec anxin-mysql-prod mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -e "SELECT 1;" 2>/dev/null; then
            log_success "✓ root用户连接成功"
        else
            log_error "✗ root用户连接失败"
        fi
        
        # 测试应用用户连接
        log_info "测试应用用户连接..."
        if docker exec anxin-mysql-prod mysql -u"$DB_USER" -p"$DB_PASSWORD" -e "SELECT 1;" "$DB_NAME" 2>/dev/null; then
            log_success "✓ 应用用户连接成功"
        else
            log_error "✗ 应用用户连接失败"
        fi
        
        # 检查数据库是否存在
        log_info "检查数据库是否存在..."
        if docker exec anxin-mysql-prod mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -e "SHOW DATABASES;" | grep -q "$DB_NAME"; then
            log_success "✓ 数据库 $DB_NAME 存在"
        else
            log_error "✗ 数据库 $DB_NAME 不存在"
        fi
    fi
}

# 检查后端服务连接配置
check_backend_connection_config() {
    log_info "检查后端服务连接配置..."
    
    if docker ps --filter "name=anxin-backend-prod" --format "{{.Names}}" | grep -q "anxin-backend-prod"; then
        log_success "✓ 后端容器正在运行"
        
        # 检查环境变量
        echo "数据库连接环境变量:"
        docker exec anxin-backend-prod env | grep -E "^DB_" | while read line; do
            if [[ $line == *"PASSWORD"* ]]; then
                echo "  ${line%%=*}=[HIDDEN]"
            else
                echo "  $line"
            fi
        done
        
        # 检查网络连通性
        log_info "测试容器间网络连通性..."
        if docker exec anxin-backend-prod nc -z anxin-mysql 3306 2>/dev/null; then
            log_success "✓ 后端容器可以连接到MySQL容器"
        else
            log_error "✗ 后端容器无法连接到MySQL容器"
        fi
    else
        log_error "✗ 后端容器未运行"
    fi
}

# 检查应用日志中的连接错误
check_connection_errors() {
    log_info "检查应用日志中的连接错误..."
    
    echo "最近的数据库连接错误:"
    echo "----------------------------------------"
    ./deploy.sh logs backend -e production --tail 100 | grep -i -E "(connection|datasource|mysql|jdbc)" | tail -10 || echo "未找到相关日志"
    echo "----------------------------------------"
    
    # 检查是否有连接池相关错误
    if ./deploy.sh logs backend -e production --tail 200 | grep -i "DataSourceClosedException"; then
        log_error "发现数据源关闭异常"
    fi
    
    if ./deploy.sh logs backend -e production --tail 200 | grep -i "CannotGetJdbcConnectionException"; then
        log_error "发现JDBC连接获取异常"
    fi
}

# 修复数据库连接问题
fix_database_connection() {
    log_info "尝试修复数据库连接问题..."
    
    # 1. 重启MySQL服务
    log_info "重启MySQL服务..."
    ./deploy.sh restart mysql -e production
    sleep 10
    
    # 2. 等待MySQL完全启动
    log_info "等待MySQL服务完全启动..."
    local max_attempts=30
    local attempt=1
    
    while [ $attempt -le $max_attempts ]; do
        if docker exec anxin-mysql-prod mysqladmin ping -h localhost -u root -p"$MYSQL_ROOT_PASSWORD" 2>/dev/null; then
            log_success "MySQL服务已就绪"
            break
        fi
        
        echo "等待MySQL服务... (尝试 $attempt/$max_attempts)"
        sleep 2
        attempt=$((attempt + 1))
    done
    
    if [ $attempt -gt $max_attempts ]; then
        log_error "MySQL服务启动超时"
        return 1
    fi
    
    # 3. 重启后端服务
    log_info "重启后端服务..."
    ./deploy.sh restart backend -e production
    sleep 15
    
    # 4. 检查修复结果
    log_info "检查修复结果..."
    if ./deploy.sh logs backend -e production --tail 20 | grep -i "started.*in"; then
        log_success "✓ 后端服务启动成功"
    else
        log_warn "后端服务启动状态未知，请检查日志"
    fi
}

# 显示修复建议
show_fix_suggestions() {
    log_info "修复建议:"
    echo "========================================"
    echo "如果问题仍然存在，请尝试以下步骤:"
    echo ""
    echo "1. 完全重启所有服务:"
    echo "   ./deploy.sh down -e production"
    echo "   ./deploy.sh up -e production"
    echo ""
    echo "2. 检查数据库用户权限:"
    echo "   docker exec anxin-mysql-prod mysql -uroot -p"
    echo "   SHOW GRANTS FOR 'anxin_prod'@'%';"
    echo ""
    echo "3. 检查数据库配置:"
    echo "   docker exec anxin-mysql-prod mysql -uroot -p -e \"SHOW VARIABLES LIKE 'max_connections';\""
    echo ""
    echo "4. 如果是连接池配置问题，检查application-docker.yml中的Druid配置"
    echo ""
    echo "5. 监控资源使用情况:"
    echo "   docker stats anxin-mysql-prod anxin-backend-prod"
    echo "========================================"
}

# 主函数
main() {
    local action=${1:-"diagnose"}
    
    log_info "数据库连接诊断工具"
    echo "========================================"
    
    case $action in
        "diagnose")
            check_database_service
            echo ""
            test_database_connection
            echo ""
            check_backend_connection_config
            echo ""
            check_connection_errors
            echo ""
            show_fix_suggestions
            ;;
        "fix")
            if [[ -f "environments/.env.production" ]]; then
                source environments/.env.production
                fix_database_connection
                echo ""
                main "diagnose"
            else
                log_error "未找到环境配置文件"
            fi
            ;;
        *)
            echo "用法: $0 [diagnose|fix]"
            echo "  diagnose - 诊断数据库连接问题（默认）"
            echo "  fix      - 尝试修复数据库连接问题"
            exit 1
            ;;
    esac
    
    echo "========================================"
    log_success "操作完成!"
}

# 如果脚本被直接执行
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    main "$@"
fi