#!/bin/bash

# QAUP 环境验证脚本

set -e

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
ENV_FILE="$PROJECT_ROOT/.env"

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

print_message() {
    local color=$1
    local message=$2
    echo -e "${color}${message}${NC}"
}

# 检查系统要求
check_system_requirements() {
    print_message $BLUE "检查系统要求..."
    
    local errors=0
    
    # 检查操作系统
    if [[ "$OSTYPE" == "linux-gnu"* ]]; then
        print_message $GREEN "✓ 操作系统: Linux"
    else
        print_message $YELLOW "⚠ 操作系统: $OSTYPE (建议使用 Linux)"
    fi
    
    # 检查 Docker
    if command -v docker &> /dev/null; then
        local docker_version=$(docker --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
        print_message $GREEN "✓ Docker: $docker_version"
        
        # 检查 Docker 版本
        local major_version=$(echo $docker_version | cut -d. -f1)
        local minor_version=$(echo $docker_version | cut -d. -f2)
        
        if [ $major_version -lt 20 ] || ([ $major_version -eq 20 ] && [ $minor_version -lt 10 ]); then
            print_message $YELLOW "⚠ Docker 版本较低，建议升级到 20.10+"
        fi
    else
        print_message $RED "✗ Docker 未安装"
        errors=$((errors + 1))
    fi
    
    # 检查 Docker Compose
    if command -v docker-compose &> /dev/null; then
        local compose_version=$(docker-compose --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
        print_message $GREEN "✓ Docker Compose: $compose_version"
    else
        print_message $RED "✗ Docker Compose 未安装"
        errors=$((errors + 1))
    fi
    
    # 检查内存
    local total_mem=$(free -m | awk 'NR==2{printf "%.0f", $2/1024}')
    if [ $total_mem -ge 4 ]; then
        print_message $GREEN "✓ 内存: ${total_mem}GB"
    else
        print_message $YELLOW "⚠ 内存: ${total_mem}GB (建议至少 4GB)"
    fi
    
    # 检查磁盘空间
    local available_space=$(df -BG . | awk 'NR==2 {print $4}' | sed 's/G//')
    if [ $available_space -ge 20 ]; then
        print_message $GREEN "✓ 可用磁盘空间: ${available_space}GB"
    else
        print_message $YELLOW "⚠ 可用磁盘空间: ${available_space}GB (建议至少 20GB)"
    fi
    
    return $errors
}

# 检查端口占用
check_ports() {
    print_message $BLUE "检查端口占用..."
    
    local ports=(80 443 8080 5432 6379)
    local occupied_ports=()
    
    for port in "${ports[@]}"; do
        if netstat -tuln 2>/dev/null | grep -q ":$port "; then
            occupied_ports+=($port)
            print_message $YELLOW "⚠ 端口 $port 已被占用"
        else
            print_message $GREEN "✓ 端口 $port 可用"
        fi
    done
    
    if [ ${#occupied_ports[@]} -gt 0 ]; then
        print_message $YELLOW "警告: 以下端口被占用: ${occupied_ports[*]}"
        print_message $YELLOW "请在 .env 文件中修改端口配置或停止占用端口的服务"
        return 1
    fi
    
    return 0
}

# 检查 Docker 服务状态
check_docker_service() {
    print_message $BLUE "检查 Docker 服务状态..."
    
    if systemctl is-active --quiet docker; then
        print_message $GREEN "✓ Docker 服务正在运行"
    else
        print_message $RED "✗ Docker 服务未运行"
        print_message $YELLOW "请运行: sudo systemctl start docker"
        return 1
    fi
    
    # 检查当前用户是否在 docker 组中
    if groups | grep -q docker; then
        print_message $GREEN "✓ 当前用户在 docker 组中"
    else
        print_message $YELLOW "⚠ 当前用户不在 docker 组中"
        print_message $YELLOW "请运行: sudo usermod -aG docker $USER"
        print_message $YELLOW "然后重新登录或运行: newgrp docker"
    fi
    
    return 0
}

# 检查环境配置
check_environment_config() {
    print_message $BLUE "检查环境配置..."
    
    local errors=0
    
    # 检查环境文件
    if [ ! -f "$ENV_FILE" ]; then
        print_message $RED "✗ 环境文件不存在: $ENV_FILE"
        print_message $YELLOW "请运行: docker/config-manager.sh init"
        return 1
    fi
    
    source "$ENV_FILE"
    
    # 检查必需的环境变量
    local required_vars=(
        "POSTGRES_DB"
        "POSTGRES_USER"
        "POSTGRES_PASSWORD"
        "APP_DB_USER"
        "APP_DB_PASSWORD"
    )
    
    for var in "${required_vars[@]}"; do
        if [ -z "${!var}" ]; then
            print_message $RED "✗ 必需的环境变量未设置: $var"
            errors=$((errors + 1))
        else
            print_message $GREEN "✓ $var 已设置"
        fi
    done
    
    # 检查密码强度
    if [ ${#POSTGRES_PASSWORD} -lt 8 ]; then
        print_message $YELLOW "⚠ PostgreSQL 密码长度少于8位"
        errors=$((errors + 1))
    fi
    
    if [ ${#APP_DB_PASSWORD} -lt 8 ]; then
        print_message $YELLOW "⚠ 应用数据库密码长度少于8位"
        errors=$((errors + 1))
    fi
    
    return $errors
}

# 检查文件权限
check_file_permissions() {
    print_message $BLUE "检查文件权限..."
    
    local errors=0
    
    # 检查脚本文件权限
    local script_files=(
        "docker/start.sh"
        "docker/build-frontend.sh"
        "docker/nginx/start-nginx.sh"
        "docker/postgres/init-db.sh"
        "docker/postgres/db-manager.sh"
        "docker/prepare-offline-images.sh"
        "docker/load-images.sh"
        "docker/docker-compose-manager.sh"
        "docker/config-manager.sh"
        "docker/secrets-manager.sh"
    )
    
    for script in "${script_files[@]}"; do
        local script_path="$PROJECT_ROOT/$script"
        if [ -f "$script_path" ]; then
            if [ -x "$script_path" ]; then
                print_message $GREEN "✓ $script 可执行"
            else
                print_message $YELLOW "⚠ $script 不可执行"
                chmod +x "$script_path"
                print_message $GREEN "✓ 已修复 $script 权限"
            fi
        else
            print_message $RED "✗ 脚本文件不存在: $script"
            errors=$((errors + 1))
        fi
    done
    
    return $errors
}

# 检查目录结构
check_directory_structure() {
    print_message $BLUE "检查目录结构..."
    
    local required_dirs=(
        "docker"
        "docker/nginx"
        "docker/postgres"
        "config"
    )
    
    local errors=0
    
    for dir in "${required_dirs[@]}"; do
        local dir_path="$PROJECT_ROOT/$dir"
        if [ -d "$dir_path" ]; then
            print_message $GREEN "✓ 目录存在: $dir"
        else
            print_message $RED "✗ 目录不存在: $dir"
            errors=$((errors + 1))
        fi
    done
    
    return $errors
}

# 检查 Docker 镜像
check_docker_images() {
    print_message $BLUE "检查 Docker 镜像..."
    
    # 从 image-versions.env 文件中读取镜像配置
    local image_versions_file="$SCRIPT_DIR/image-versions.env"
    if [ -f "$image_versions_file" ]; then
        source "$image_versions_file"
    else
        print_message $RED "✗ 镜像版本配置文件不存在: $image_versions_file"
        return 1
    fi
    
    # 使用配置文件中定义的镜像名称
    local base_images=(
        "$POSTGRES_IMAGE"
        "$REDIS_IMAGE"
        "$QAUP_APP_IMAGE"
        "$QAUP_NGINX_IMAGE"
    )
    
    local missing_images=()
    
    for image in "${base_images[@]}"; do
        if docker image inspect "$image" &> /dev/null; then
            print_message $GREEN "✓ 镜像存在: $image"
        else
            missing_images+=("$image")
            print_message $YELLOW "⚠ 镜像不存在: $image"
        fi
    done
    
    if [ ${#missing_images[@]} -gt 0 ]; then
        print_message $YELLOW "缺失的镜像: ${missing_images[*]}"
        print_message $YELLOW "请运行: ./docker/prepare-offline-images.sh 或手动拉取镜像"
        return 1
    fi
    
    return 0
}

# 生成验证报告
generate_report() {
    local total_errors=$1
    
    print_message $BLUE "========================================="
    print_message $BLUE "环境验证报告"
    print_message $BLUE "========================================="
    
    if [ $total_errors -eq 0 ]; then
        print_message $GREEN "✓ 环境验证通过，可以开始部署"
        print_message $GREEN "建议的下一步操作:"
        echo "  1. 运行: docker/docker-compose-manager.sh prod build"
        echo "  2. 运行: docker/docker-compose-manager.sh prod start"
    else
        print_message $RED "✗ 环境验证失败，发现 $total_errors 个问题"
        print_message $YELLOW "请修复上述问题后重新运行验证"
    fi
    
    print_message $BLUE "========================================="
}

# 主函数
main() {
    print_message $GREEN "开始 QAUP 环境验证..."
    print_message $BLUE "========================================="
    
    local total_errors=0
    
    # 执行各项检查
    check_system_requirements
    total_errors=$((total_errors + $?))
    
    echo ""
    check_docker_service
    total_errors=$((total_errors + $?))
    
    echo ""
    check_ports
    total_errors=$((total_errors + $?))
    
    echo ""
    check_directory_structure
    total_errors=$((total_errors + $?))
    
    echo ""
    check_file_permissions
    total_errors=$((total_errors + $?))
    
    echo ""
    check_environment_config
    total_errors=$((total_errors + $?))
    
    echo ""
    check_docker_images
    total_errors=$((total_errors + $?))
    
    echo ""
    generate_report $total_errors
    
    exit $total_errors
}

main "$@"