@echo off
REM Kubernetes 自动部署脚本 (Windows 版本)
REM 用于从私有 Harbor 仓库拉取 NGINX 镜像并部署到 K8s 集群

setlocal EnableDelayedExpansion

REM 设置颜色代码（Windows 10/11 支持 ANSI 转义序列）
set "RED=[91m"
set "GREEN=[92m"
set "YELLOW=[93m"
set "BLUE=[94m"
set "NC=[0m"

REM 打印带颜色的信息
:print_info
echo %BLUE%[INFO]%NC% %~1
goto :eof

:print_success
echo %GREEN%[SUCCESS]%NC% %~1
goto :eof

:print_warning
echo %YELLOW%[WARNING]%NC% %~1
goto :eof

:print_error
echo %RED%[ERROR]%NC% %~1
goto :eof

REM 检查必要的环境变量
:check_env_vars
call :print_info "检查环境变量..."

set "missing_vars="
if "%HARBOR_REGISTRY%"=="" set "missing_vars=%missing_vars% HARBOR_REGISTRY"
if "%HARBOR_USERNAME%"=="" set "missing_vars=%missing_vars% HARBOR_USERNAME"
if "%HARBOR_PASSWORD%"=="" set "missing_vars=%missing_vars% HARBOR_PASSWORD"
if "%NGINX_IMAGE_TAG%"=="" set "missing_vars=%missing_vars% NGINX_IMAGE_TAG"

if not "%missing_vars%"=="" (
    call :print_error "缺少必要的环境变量: %missing_vars%"
    echo.
    echo 请设置以下环境变量:
    echo   set HARBOR_REGISTRY=^<你的Harbor仓库地址^>
    echo   set HARBOR_USERNAME=^<Harbor用户名^>
    echo   set HARBOR_PASSWORD=^<Harbor密码^>
    echo   set NGINX_IMAGE_TAG=^<镜像标签，如: %%GITHUB_SHA%% 或 latest^>
    echo.
    echo 或者创建 .env 文件包含这些变量
    exit /b 1
)

call :print_success "环境变量检查通过"
goto :eof

REM 检查 kubectl 连接
:check_kubectl
call :print_info "检查 kubectl 连接..."

kubectl version --client >nul 2>&1
if errorlevel 1 (
    call :print_error "kubectl 未安装或不在 PATH 中"
    echo 请从 https://kubernetes.io/docs/tasks/tools/install-kubectl-windows/ 安装 kubectl
    exit /b 1
)

kubectl cluster-info >nul 2>&1
if errorlevel 1 (
    call :print_error "无法连接到 Kubernetes 集群"
    echo 请确保:
    echo   1. kubectl 已正确配置
    echo   2. 能够访问 Kubernetes 集群
    echo   3. 当前用户有适当的权限
    exit /b 1
)

call :print_success "kubectl 连接正常"
kubectl cluster-info --short
goto :eof

REM 创建命名空间（如果不存在）
:create_namespace
set "namespace=%~1"
if "%namespace%"=="" set "namespace=default"

call :print_info "检查命名空间: %namespace%"

kubectl get namespace %namespace% >nul 2>&1
if errorlevel 1 (
    call :print_info "创建命名空间: %namespace%"
    kubectl create namespace %namespace%
    if errorlevel 1 (
        call :print_error "创建命名空间失败"
        exit /b 1
    )
    call :print_success "命名空间 '%namespace%' 创建成功"
) else (
    call :print_success "命名空间 '%namespace%' 已存在"
)
goto :eof

REM 创建或更新 Harbor 仓库访问凭据
:create_harbor_secret
set "namespace=%~1"
if "%namespace%"=="" set "namespace=default"

call :print_info "创建/更新 Harbor 仓库访问凭据..."

REM 删除已存在的 secret（如果存在）
kubectl delete secret harbor-registry-secret -n %namespace% --ignore-not-found=true >nul 2>&1

REM 创建新的 secret
kubectl create secret docker-registry harbor-registry-secret --docker-server=%HARBOR_REGISTRY% --docker-username=%HARBOR_USERNAME% --docker-password=%HARBOR_PASSWORD% --namespace=%namespace%
if errorlevel 1 (
    call :print_error "创建 Harbor 仓库访问凭据失败"
    exit /b 1
)

call :print_success "Harbor 仓库访问凭据创建成功"
goto :eof

REM 更新部署文件中的镜像标签
:update_deployment_image
set "deployment_file=%~1"
set "image_tag=%~2"

call :print_info "更新部署文件中的镜像标签: %image_tag%"

set "full_image=%HARBOR_REGISTRY%/test/nginx:%image_tag%"

REM 备份原文件
copy "%deployment_file%" "%deployment_file%.bak" >nul

REM 使用 PowerShell 替换镜像标签
powershell -Command "(Get-Content '%deployment_file%') -replace '%HARBOR_REGISTRY%/test/nginx:[^\s]*', '%full_image%' | Set-Content '%deployment_file%'"
if errorlevel 1 (
    call :print_error "更新镜像标签失败"
    exit /b 1
)

call :print_success "镜像标签更新为: %full_image%"
goto :eof

REM 应用 Kubernetes 配置
:apply_k8s_config
set "deployment_file=%~1"
call :print_info "应用 Kubernetes 配置..."

if not exist "%deployment_file%" (
    call :print_error "部署文件不存在: %deployment_file%"
    exit /b 1
)

kubectl apply -f "%deployment_file%"
if errorlevel 1 (
    call :print_error "应用 Kubernetes 配置失败"
    exit /b 1
)

call :print_success "Kubernetes 配置应用成功"
goto :eof

REM 等待部署就绪
:wait_for_deployment
set "deployment_name=nginx-deployment"
set "namespace=%~1"
set "timeout=%~2"
if "%namespace%"=="" set "namespace=default"
if "%timeout%"=="" set "timeout=300"

call :print_info "等待部署就绪..."

kubectl wait --for=condition=available deployment/%deployment_name% --namespace=%namespace% --timeout=%timeout%s
if errorlevel 1 (
    call :print_error "部署超时，请检查部署状态"
    kubectl describe deployment %deployment_name% -n %namespace%
    exit /b 1
)

call :print_success "部署已就绪"
goto :eof

REM 显示部署状态
:show_deployment_status
set "namespace=%~1"
if "%namespace%"=="" set "namespace=default"

call :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>nul || echo HPA 未启用

echo.
echo === Events ===
kubectl get events --sort-by=.metadata.creationTimestamp -n %namespace% | findstr /C:"nginx"
goto :eof

REM 获取访问信息
:get_access_info
set "namespace=%~1"
if "%namespace%"=="" set "namespace=default"

call :print_info "获取访问信息..."

for /f "tokens=*" %%i in ('kubectl get service nginx-service -n %namespace% -o jsonpath^="{.spec.type}"') do set "service_type=%%i"

if "%service_type%"=="NodePort" (
    for /f "tokens=*" %%i in ('kubectl get service nginx-service -n %namespace% -o jsonpath^="{.spec.ports[0].nodePort}"') do set "node_port=%%i"
    for /f "tokens=*" %%i in ('kubectl get nodes -o jsonpath^="{.items[0].status.addresses[?(@.type==\"InternalIP\")].address}"') do set "node_ip=%%i"
    call :print_success "NodePort 访问地址: http://!node_ip!:!node_port!"
) else if "%service_type%"=="LoadBalancer" (
    call :print_info "等待 LoadBalancer 外部 IP..."
    for /f "tokens=*" %%i in ('kubectl get service nginx-service -n %namespace% -o jsonpath^="{.status.loadBalancer.ingress[0].ip}" 2^>nul') do set "external_ip=%%i"
    if not "!external_ip!"=="" (
        call :print_success "LoadBalancer 访问地址: http://!external_ip!"
    ) else (
        call :print_warning "LoadBalancer 外部 IP 仍在分配中"
    )
) else if "%service_type%"=="ClusterIP" (
    for /f "tokens=*" %%i in ('kubectl get service nginx-service -n %namespace% -o jsonpath^="{.spec.clusterIP}"') do set "cluster_ip=%%i"
    call :print_success "ClusterIP 访问地址: http://!cluster_ip!"
    call :print_info "注意: ClusterIP 只能在集群内部访问"
)
goto :eof

REM 清理函数
:cleanup
call :print_info "执行清理操作..."
if exist ".\nginx-deployment.yaml.bak" (
    move ".\nginx-deployment.yaml.bak" ".\nginx-deployment.yaml" >nul
)
goto :eof

REM 主函数
:main
call :print_info "开始 NGINX Kubernetes 自动部署..."

REM 设置默认值
if "%NAMESPACE%"=="" set "NAMESPACE=default"
if "%DEPLOYMENT_FILE%"=="" set "DEPLOYMENT_FILE=.\nginx-deployment.yaml"
if "%NGINX_IMAGE_TAG%"=="" set "NGINX_IMAGE_TAG=latest"

REM 检查是否有 .env 文件
if exist ".env" (
    call :print_info "加载 .env 文件..."
    for /f "usebackq tokens=1,2 delims==" %%a in (".env") do (
        set "%%a=%%b"
    )
)

REM 执行部署步骤
call :check_env_vars
if errorlevel 1 exit /b 1

call :check_kubectl
if errorlevel 1 exit /b 1

call :create_namespace "%NAMESPACE%"
if errorlevel 1 exit /b 1

call :create_harbor_secret "%NAMESPACE%"
if errorlevel 1 exit /b 1

call :update_deployment_image "%DEPLOYMENT_FILE%" "%NGINX_IMAGE_TAG%"
if errorlevel 1 exit /b 1

call :apply_k8s_config "%DEPLOYMENT_FILE%"
if errorlevel 1 exit /b 1

call :wait_for_deployment "%NAMESPACE%"
if errorlevel 1 exit /b 1

call :show_deployment_status "%NAMESPACE%"
call :get_access_info "%NAMESPACE%"

call :print_success "🎉 NGINX 部署完成！"
goto :eof

REM 如果直接运行此脚本，执行主函数
call :main
call :cleanup
