#!/bin/bash
# 环境管理脚本 - 用于切换不同环境的Docker Compose配置
# Requirements: 5.3, 6.5

set -e

# 脚本目录
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DOCKER_DIR="$(dirname "$SCRIPT_DIR")"
PROJECT_ROOT="$(dirname "$DOCKER_DIR")"

# 颜色定义
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 "${GREEN}[INFO]${NC} $1"
}

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

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

log_debug() {
    echo -e "${BLUE}[DEBUG]${NC} $1"
}

# 显示帮助信息
show_help() {
    cat << EOF
环境管理脚本 - 若依框架Docker部署

用法: $0 [命令] [环境]

命令:
    deploy      部署指定环境
    stop        停止指定环境
    restart     重启指定环境
    status      查看指定环境状态
    logs        查看指定环境日志
    clean       清理指定环境
    backup      备份指定环境数据
    list        列出所有可用环境
    help        显示此帮助信息

环境:
    development (dev)    开发环境
    staging     (stage)  测试环境
    production  (prod)   生产环境

示例:
    $0 deploy development    # 部署开发环境
    $0 stop prod            # 停止生产环境
    $0 logs staging         # 查看测试环境日志
    $0 status dev           # 查看开发环境状态

EOF
}

# 验证环境参数
validate_environment() {
    local env=$1
    case $env in
        development|dev)
            echo "development"
            ;;
        staging|stage)
            echo "staging"
            ;;
        production|prod)
            echo "production"
            ;;
        *)
            log_error "无效的环境: $env"
            log_info "支持的环境: development, staging, production"
            exit 1
            ;;
    esac
}

# 获取compose文件路径
get_compose_file() {
    local env=$1
    echo "${DOCKER_DIR}/docker-compose.${env}.yml"
}

# 获取环境配置文件路径
get_env_file() {
    local env=$1
    echo "${DOCKER_DIR}/environments/.env.${env}"
}

# 检查文件是否存在
check_files() {
    local env=$1
    local compose_file=$(get_compose_file $env)
    local env_file=$(get_env_file $env)
    
    if [ ! -f "$compose_file" ]; then
        log_error "Compose文件不存在: $compose_file"
        exit 1
    fi
    
    if [ ! -f "$env_file" ]; then
        log_error "环境配置文件不存在: $env_file"
        exit 1
    fi
    
    log_debug "文件检查通过: $compose_file, $env_file"
}

# 部署环境
deploy_environment() {
    local env=$1
    local compose_file=$(get_compose_file $env)
    local env_file=$(get_env_file $env)
    
    log_info "开始部署 $env 环境..."
    
    # 检查文件
    check_files $env
    
    # 创建必要的目录
    log_info "创建数据目录..."
    source "$env_file"
    mkdir -p "${MYSQL_DATA_PATH:-./data/$env/mysql}"
    mkdir -p "${MYSQL_LOG_PATH:-./data/$env/mysql-logs}"
    mkdir -p "${BACKEND_LOG_PATH:-./data/$env/backend-logs}"
    mkdir -p "${BACKEND_UPLOAD_PATH:-./data/$env/uploads}"
    mkdir -p "${FRONTEND_LOG_PATH:-./data/$env/nginx-logs}"
    
    if [ "$env" != "development" ]; then
        mkdir -p "${BACKUP_DATA_PATH:-./data/$env/backups}"
    fi
    
    # 部署服务
    log_info "启动Docker Compose服务..."
    cd "$DOCKER_DIR"
    docker-compose -f "$compose_file" --env-file "$env_file" up -d
    
    # 等待服务启动
    log_info "等待服务启动..."
    sleep 10
    
    # 检查服务状态
    check_services $env
    
    log_info "$env 环境部署完成!"
}

# 停止环境
stop_environment() {
    local env=$1
    local compose_file=$(get_compose_file $env)
    local env_file=$(get_env_file $env)
    
    log_info "停止 $env 环境..."
    
    cd "$DOCKER_DIR"
    docker-compose -f "$compose_file" --env-file "$env_file" down
    
    log_info "$env 环境已停止"
}

# 重启环境
restart_environment() {
    local env=$1
    
    log_info "重启 $env 环境..."
    stop_environment $env
    sleep 5
    deploy_environment $env
}

# 查看环境状态
check_services() {
    local env=$1
    local compose_file=$(get_compose_file $env)
    local env_file=$(get_env_file $env)
    
    log_info "检查 $env 环境服务状态..."
    
    cd "$DOCKER_DIR"
    docker-compose -f "$compose_file" --env-file "$env_file" ps
    
    # 健康检查
    log_info "执行健康检查..."
    local services=("anxin-mysql-${env}" "anxin-backend-${env}" "anxin-frontend-${env}")
    
    for service in "${services[@]}"; do
        if docker ps --format "table {{.Names}}" | grep -q "$service"; then
            local health=$(docker inspect --format='{{.State.Health.Status}}' "$service" 2>/dev/null || echo "no-healthcheck")
            if [ "$health" = "healthy" ] || [ "$health" = "no-healthcheck" ]; then
                log_info "✓ $service: 运行正常"
            else
                log_warn "⚠ $service: 健康检查失败 ($health)"
            fi
        else
            log_error "✗ $service: 未运行"
        fi
    done
}

# 查看日志
view_logs() {
    local env=$1
    local service=$2
    local compose_file=$(get_compose_file $env)
    local env_file=$(get_env_file $env)
    
    cd "$DOCKER_DIR"
    
    if [ -n "$service" ]; then
        log_info "查看 $env 环境 $service 服务日志..."
        docker-compose -f "$compose_file" --env-file "$env_file" logs -f "$service"
    else
        log_info "查看 $env 环境所有服务日志..."
        docker-compose -f "$compose_file" --env-file "$env_file" logs -f
    fi
}

# 清理环境
clean_environment() {
    local env=$1
    local compose_file=$(get_compose_file $env)
    local env_file=$(get_env_file $env)
    
    log_warn "即将清理 $env 环境 (包括数据卷)..."
    read -p "确认继续? (y/N): " -n 1 -r
    echo
    
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        log_info "清理 $env 环境..."
        cd "$DOCKER_DIR"
        docker-compose -f "$compose_file" --env-file "$env_file" down -v --remove-orphans
        docker system prune -f
        log_info "$env 环境清理完成"
    else
        log_info "取消清理操作"
    fi
}

# 备份环境数据
backup_environment() {
    local env=$1
    
    log_info "备份 $env 环境数据..."
    
    case $env in
        production)
            docker exec anxin-mysql-prod /backup.sh
            ;;
        staging)
            docker exec anxin-mysql-staging /backup.sh
            ;;
        development)
            log_warn "开发环境通常不需要备份"
            ;;
    esac
    
    log_info "$env 环境数据备份完成"
}

# 列出所有环境
list_environments() {
    log_info "可用环境:"
    echo "  development (dev)  - 开发环境"
    echo "  staging     (stage) - 测试环境"
    echo "  production  (prod)  - 生产环境"
    echo
    
    log_info "当前运行的容器:"
    docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep anxin || echo "  无运行中的容器"
}

# 主函数
main() {
    local command=$1
    local environment=$2
    
    case $command in
        deploy)
            if [ -z "$environment" ]; then
                log_error "请指定环境"
                show_help
                exit 1
            fi
            env=$(validate_environment "$environment")
            deploy_environment "$env"
            ;;
        stop)
            if [ -z "$environment" ]; then
                log_error "请指定环境"
                show_help
                exit 1
            fi
            env=$(validate_environment "$environment")
            stop_environment "$env"
            ;;
        restart)
            if [ -z "$environment" ]; then
                log_error "请指定环境"
                show_help
                exit 1
            fi
            env=$(validate_environment "$environment")
            restart_environment "$env"
            ;;
        status)
            if [ -z "$environment" ]; then
                log_error "请指定环境"
                show_help
                exit 1
            fi
            env=$(validate_environment "$environment")
            check_services "$env"
            ;;
        logs)
            if [ -z "$environment" ]; then
                log_error "请指定环境"
                show_help
                exit 1
            fi
            env=$(validate_environment "$environment")
            view_logs "$env" "$3"
            ;;
        clean)
            if [ -z "$environment" ]; then
                log_error "请指定环境"
                show_help
                exit 1
            fi
            env=$(validate_environment "$environment")
            clean_environment "$env"
            ;;
        backup)
            if [ -z "$environment" ]; then
                log_error "请指定环境"
                show_help
                exit 1
            fi
            env=$(validate_environment "$environment")
            backup_environment "$env"
            ;;
        list)
            list_environments
            ;;
        help|--help|-h)
            show_help
            ;;
        *)
            log_error "未知命令: $command"
            show_help
            exit 1
            ;;
    esac
}

# 检查Docker是否安装
if ! command -v docker &> /dev/null; then
    log_error "Docker未安装或不在PATH中"
    exit 1
fi

if ! command -v docker-compose &> /dev/null; then
    log_error "Docker Compose未安装或不在PATH中"
    exit 1
fi

# 执行主函数
main "$@"