#!/bin/bash

# Kubernetes 自动部署脚本
# 用于从私有 Harbor 仓库拉取 NGINX 镜像并部署到 K8s 集群

set -e

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

# 打印带颜色的信息
print_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

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

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

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

# 检查必要的环境变量
check_env_vars() {
    print_info "检查环境变量..."
    
    required_vars=("HARBOR_REGISTRY" "HARBOR_USERNAME" "HARBOR_PASSWORD" "NGINX_IMAGE_TAG")
    missing_vars=()
    
    for var in "${required_vars[@]}"; do
        if [[ -z "${!var}" ]]; then
            missing_vars+=("$var")
        fi
    done
    
    if [[ ${#missing_vars[@]} -gt 0 ]]; then
        print_error "缺少必要的环境变量:"
        for var in "${missing_vars[@]}"; do
            echo "  - $var"
        done
        print_info "请设置以下环境变量:"
        echo "  export HARBOR_REGISTRY=<你的Harbor仓库地址>"
        echo "  export HARBOR_USERNAME=<Harbor用户名>"
        echo "  export HARBOR_PASSWORD=<Harbor密码>"
        echo "  export NGINX_IMAGE_TAG=<镜像标签，如: \${GITHUB_SHA} 或 latest>"
        exit 1
    fi
    
    print_success "环境变量检查通过"
}

# 检查 kubectl 连接
check_kubectl() {
    print_info "检查 kubectl 连接..."
    
    if ! command -v kubectl &> /dev/null; then
        print_error "kubectl 未安装或不在 PATH 中"
        exit 1
    fi
    
    if ! kubectl cluster-info &> /dev/null; then
        print_error "无法连接到 Kubernetes 集群"
        print_info "请确保:"
        echo "  1. kubectl 已正确配置"
        echo "  2. 能够访问 Kubernetes 集群"
        echo "  3. 当前用户有适当的权限"
        exit 1
    fi
    
    print_success "kubectl 连接正常"
    kubectl cluster-info --short
}

# 创建命名空间（如果不存在）
create_namespace() {
    local namespace=${1:-default}
    print_info "检查命名空间: $namespace"
    
    if kubectl get namespace "$namespace" &> /dev/null; then
        print_success "命名空间 '$namespace' 已存在"
    else
        print_info "创建命名空间: $namespace"
        kubectl create namespace "$namespace"
        print_success "命名空间 '$namespace' 创建成功"
    fi
}

# 创建或更新 Harbor 仓库访问凭据
create_harbor_secret() {
    local namespace=${1:-default}
    print_info "创建/更新 Harbor 仓库访问凭据..."
    
    # 删除已存在的 secret（如果存在）
    kubectl delete secret harbor-registry-secret -n "$namespace" --ignore-not-found=true
    
    # 创建新的 secret
    kubectl create secret docker-registry harbor-registry-secret \
        --docker-server="$HARBOR_REGISTRY" \
        --docker-username="$HARBOR_USERNAME" \
        --docker-password="$HARBOR_PASSWORD" \
        --namespace="$namespace"
    
    print_success "Harbor 仓库访问凭据创建成功"
}

# 更新部署文件中的镜像标签
update_deployment_image() {
    local deployment_file="$1"
    local image_tag="$2"
    
    print_info "更新部署文件中的镜像标签: $image_tag"
    
    # 使用 sed 替换镜像标签
    local full_image="${HARBOR_REGISTRY}/test/nginx:${image_tag}"
    
    # 备份原文件
    cp "$deployment_file" "${deployment_file}.bak"
    
    # 替换镜像标签 (假设镜像行包含 harbor-registry/test/nginx)
    sed -i.tmp "s|${HARBOR_REGISTRY}/test/nginx:[^[:space:]]*|${full_image}|g" "$deployment_file"
    
    print_success "镜像标签更新为: $full_image"
}

# 应用 Kubernetes 配置
apply_k8s_config() {
    local deployment_file="$1"
    print_info "应用 Kubernetes 配置..."
    
    if [[ ! -f "$deployment_file" ]]; then
        print_error "部署文件不存在: $deployment_file"
        exit 1
    fi
    
    kubectl apply -f "$deployment_file"
    print_success "Kubernetes 配置应用成功"
}

# 等待部署就绪
wait_for_deployment() {
    local deployment_name="nginx-deployment"
    local namespace=${1:-default}
    local timeout=${2:-300}
    
    print_info "等待部署就绪..."
    
    if kubectl wait --for=condition=available deployment/"$deployment_name" \
        --namespace="$namespace" --timeout="${timeout}s"; then
        print_success "部署已就绪"
    else
        print_error "部署超时，请检查部署状态"
        kubectl describe deployment "$deployment_name" -n "$namespace"
        exit 1
    fi
}

# 显示部署状态
show_deployment_status() {
    local namespace=${1:-default}
    print_info "部署状态:"
    
    echo
    echo "=== Pods ==="
    kubectl get pods -l app=nginx -n "$namespace" -o wide
    
    echo
    echo "=== Services ==="
    kubectl get services -l app=nginx -n "$namespace"
    
    echo
    echo "=== Deployments ==="
    kubectl get deployments -l app=nginx -n "$namespace"
    
    echo
    echo "=== HPA ==="
    kubectl get hpa -l app=nginx -n "$namespace" 2>/dev/null || echo "HPA 未启用"
    
    echo
    echo "=== Events ==="
    kubectl get events --sort-by=.metadata.creationTimestamp -n "$namespace" | tail -10
}

# 获取访问信息
get_access_info() {
    local namespace=${1:-default}
    print_info "获取访问信息..."
    
    local service_type=$(kubectl get service nginx-service -n "$namespace" -o jsonpath='{.spec.type}')
    
    case "$service_type" in
        "NodePort")
            local node_port=$(kubectl get service nginx-service -n "$namespace" -o jsonpath='{.spec.ports[0].nodePort}')
            local node_ip=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="ExternalIP")].address}')
            if [[ -z "$node_ip" ]]; then
                node_ip=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}')
            fi
            print_success "NodePort 访问地址: http://${node_ip}:${node_port}"
            ;;
        "LoadBalancer")
            print_info "等待 LoadBalancer 外部 IP..."
            local external_ip=$(kubectl get service nginx-service -n "$namespace" -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
            if [[ -n "$external_ip" ]]; then
                print_success "LoadBalancer 访问地址: http://${external_ip}"
            else
                print_warning "LoadBalancer 外部 IP 仍在分配中"
            fi
            ;;
        "ClusterIP")
            local cluster_ip=$(kubectl get service nginx-service -n "$namespace" -o jsonpath='{.spec.clusterIP}')
            print_success "ClusterIP 访问地址: http://${cluster_ip}"
            print_info "注意: ClusterIP 只能在集群内部访问"
            ;;
    esac
}

# 主函数
main() {
    print_info "开始 NGINX Kubernetes 自动部署..."
    
    # 设置默认值
    local namespace=${NAMESPACE:-default}
    local deployment_file=${DEPLOYMENT_FILE:-./nginx-deployment.yaml}
    local image_tag=${NGINX_IMAGE_TAG:-latest}
    
    # 执行部署步骤
    check_env_vars
    check_kubectl
    create_namespace "$namespace"
    create_harbor_secret "$namespace"
    update_deployment_image "$deployment_file" "$image_tag"
    apply_k8s_config "$deployment_file"
    wait_for_deployment "$namespace"
    show_deployment_status "$namespace"
    get_access_info "$namespace"
    
    print_success "🎉 NGINX 部署完成！"
}

# 清理函数
cleanup() {
    print_info "执行清理操作..."
    # 恢复备份文件
    if [[ -f "./nginx-deployment.yaml.bak" ]]; then
        mv "./nginx-deployment.yaml.bak" "./nginx-deployment.yaml"
    fi
}

# 设置清理陷阱
trap cleanup EXIT

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