#!/bin/bash
# =============================================================================
# Docker Registry CI/CD 驗證腳本
# 用途: 驗證新的 Registry-based CI/CD 流程是否正常運作
# =============================================================================

set -e

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

# 配置
REGISTRY_URL="registry.wooo.work"
REGISTRY_LOCAL_URL="http://127.0.0.1:5000"
UAT_HOST="192.168.0.110"
UAT_USER="wooo"
GCP_HOST="35.194.233.141"
GCP_USER="wooo"

# 計數器
PASSED=0
FAILED=0
WARNINGS=0

# =============================================================================
# 輸出函數
# =============================================================================
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_pass() { echo -e "${GREEN}[PASS]${NC} $1"; ((PASSED++)); }
log_fail() { echo -e "${RED}[FAIL]${NC} $1"; ((FAILED++)); }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; ((WARNINGS++)); }

section() {
    echo ""
    echo "=============================================="
    echo -e "${BLUE}$1${NC}"
    echo "=============================================="
}

# =============================================================================
# 1. 本地環境檢查
# =============================================================================
check_local_env() {
    section "1. 本地環境檢查"

    # Docker
    if command -v docker &> /dev/null; then
        log_pass "Docker 已安裝: $(docker --version | cut -d' ' -f3)"
    else
        log_fail "Docker 未安裝"
    fi

    # Git
    if command -v git &> /dev/null; then
        log_pass "Git 已安裝: $(git --version | cut -d' ' -f3)"
    else
        log_fail "Git 未安裝"
    fi

    # SSH
    if command -v ssh &> /dev/null; then
        log_pass "SSH 已安裝"
    else
        log_fail "SSH 未安裝"
    fi

    # curl
    if command -v curl &> /dev/null; then
        log_pass "curl 已安裝"
    else
        log_fail "curl 未安裝"
    fi
}

# =============================================================================
# 2. SSH 連線檢查
# =============================================================================
check_ssh_connections() {
    section "2. SSH 連線檢查"

    # UAT
    if ssh -o BatchMode=yes -o ConnectTimeout=5 ${UAT_USER}@${UAT_HOST} "echo 'ok'" &> /dev/null; then
        log_pass "UAT SSH 連線正常 (${UAT_HOST})"
    else
        log_fail "UAT SSH 連線失敗 (${UAT_HOST})"
    fi

    # GCP
    if ssh -o BatchMode=yes -o ConnectTimeout=5 ${GCP_USER}@${GCP_HOST} "echo 'ok'" &> /dev/null; then
        log_pass "GCP SSH 連線正常 (${GCP_HOST})"
    else
        log_warn "GCP SSH 連線失敗 (${GCP_HOST}) - 可能需要設定 SSH Key"
    fi
}

# =============================================================================
# 3. Registry 服務檢查
# =============================================================================
check_registry_service() {
    section "3. Registry 服務檢查"

    # 本地連線測試 (透過 SSH 到 UAT)
    log_info "檢查 Registry 本地連線 (127.0.0.1:5000)..."
    local local_status=$(ssh ${UAT_USER}@${UAT_HOST} "curl -s -o /dev/null -w '%{http_code}' ${REGISTRY_LOCAL_URL}/v2/ --max-time 10" 2>/dev/null || echo "000")

    if [[ "$local_status" == "200" ]]; then
        log_pass "Registry 本地連線正常 (HTTP $local_status)"
    else
        log_fail "Registry 本地連線失敗 (HTTP $local_status)"
    fi

    # 外部 HTTPS 連線測試
    log_info "檢查 Registry 外部連線 (https://${REGISTRY_URL})..."
    local external_status=$(curl -s -o /dev/null -w "%{http_code}" "https://${REGISTRY_URL}/v2/" --max-time 10 2>/dev/null || echo "000")

    if [[ "$external_status" == "401" ]]; then
        log_pass "Registry 外部連線正常 (需要認證, HTTP 401)"
    elif [[ "$external_status" == "200" ]]; then
        log_pass "Registry 外部連線正常 (HTTP 200)"
    else
        log_fail "Registry 外部連線失敗 (HTTP $external_status)"
    fi

    # Docker 登入測試 (如果有認證資訊)
    if [[ -n "$REGISTRY_USER" && -n "$REGISTRY_PASSWORD" ]]; then
        log_info "測試 Docker 登入..."
        if echo "$REGISTRY_PASSWORD" | docker login "$REGISTRY_URL" -u "$REGISTRY_USER" --password-stdin &> /dev/null; then
            log_pass "Docker 登入成功"
            docker logout "$REGISTRY_URL" &> /dev/null
        else
            log_fail "Docker 登入失敗"
        fi
    else
        log_warn "未設定 REGISTRY_USER/REGISTRY_PASSWORD，跳過登入測試"
    fi
}

# =============================================================================
# 4. K8s 服務狀態檢查
# =============================================================================
check_k8s_services() {
    section "4. K8s 服務狀態檢查 (UAT)"

    # 檢查 Pod 狀態
    log_info "檢查 K8s Pod 狀態..."
    local pods=$(ssh ${UAT_USER}@${UAT_HOST} "kubectl get pods -n momo -o wide 2>/dev/null" || echo "error")

    if [[ "$pods" == "error" ]]; then
        log_fail "無法取得 K8s Pod 狀態"
        return
    fi

    echo "$pods"
    echo ""

    # momo-app
    if echo "$pods" | grep -q "momo-app.*Running"; then
        log_pass "momo-app Pod 運行中"
    else
        log_fail "momo-app Pod 異常"
    fi

    # momo-scheduler
    if echo "$pods" | grep -q "momo-scheduler.*Running"; then
        log_pass "momo-scheduler Pod 運行中"
    else
        log_fail "momo-scheduler Pod 異常"
    fi

    # momo-postgres
    if echo "$pods" | grep -q "momo-postgres.*Running"; then
        log_pass "momo-postgres Pod 運行中"
    else
        log_fail "momo-postgres Pod 異常"
    fi

    # 檢查 Registry Secret
    log_info "檢查 Registry Secret..."
    if ssh ${UAT_USER}@${UAT_HOST} "kubectl get secret registry-secret -n momo &>/dev/null"; then
        log_pass "registry-secret 已建立"
    else
        log_warn "registry-secret 不存在，需要建立"
    fi
}

# =============================================================================
# 5. 應用健康檢查
# =============================================================================
check_app_health() {
    section "5. 應用健康檢查"

    # UAT
    log_info "檢查 UAT 應用 (https://mo.wooo.work)..."
    local uat_health=$(curl -s "https://mo.wooo.work/health" --max-time 10 2>/dev/null || echo "error")

    if echo "$uat_health" | grep -q "healthy"; then
        log_pass "UAT 應用健康檢查通過"
    else
        log_fail "UAT 應用健康檢查失敗"
    fi

    # GCP
    log_info "檢查 GCP 應用 (https://momo.wooo.work)..."
    local gcp_health=$(curl -s "https://momo.wooo.work/health" --max-time 10 2>/dev/null || echo "error")

    if echo "$gcp_health" | grep -q "healthy"; then
        log_pass "GCP 應用健康檢查通過"
    else
        log_warn "GCP 應用健康檢查失敗 (可能尚未部署)"
    fi
}

# =============================================================================
# 6. CI/CD 配置檢查
# =============================================================================
check_cicd_config() {
    section "6. CI/CD 配置檢查"

    # .gitlab-ci.yml
    if [[ -f ".gitlab-ci.yml" ]]; then
        log_pass ".gitlab-ci.yml 存在"

        # 檢查 Registry URL
        if grep -q "REGISTRY_URL.*registry.wooo.work" .gitlab-ci.yml; then
            log_pass "REGISTRY_URL 配置正確"
        else
            log_fail "REGISTRY_URL 配置錯誤或缺失"
        fi

        # 檢查是否還有 Harbor 引用
        if grep -qi "harbor" .gitlab-ci.yml; then
            log_fail "仍有 Harbor 引用存在於 .gitlab-ci.yml"
        else
            log_pass "無 Harbor 引用"
        fi
    else
        log_fail ".gitlab-ci.yml 不存在"
    fi

    # K8s 配置
    for file in "k8s/04-momo-app.yaml" "k8s/05-scheduler.yaml"; do
        if [[ -f "$file" ]]; then
            if grep -q "registry.wooo.work" "$file"; then
                log_pass "$file 使用正確的 Registry"
            else
                log_fail "$file 未使用 registry.wooo.work"
            fi

            if grep -qi "harbor" "$file"; then
                log_fail "$file 仍有 Harbor 引用"
            fi
        else
            log_warn "$file 不存在"
        fi
    done

    # docker-compose.yml
    if [[ -f "docker-compose.yml" ]]; then
        if grep -qi "harbor" docker-compose.yml; then
            log_fail "docker-compose.yml 仍有 Harbor 引用"
        else
            log_pass "docker-compose.yml 無 Harbor 引用"
        fi
    fi
}

# =============================================================================
# 7. Registry 映像檢查
# =============================================================================
check_registry_images() {
    section "7. Registry 映像檢查"

    if [[ -z "$REGISTRY_USER" || -z "$REGISTRY_PASSWORD" ]]; then
        log_warn "未設定認證資訊，跳過映像檢查"
        return
    fi

    log_info "列出 Registry 中的映像..."
    local catalog=$(curl -s -u "${REGISTRY_USER}:${REGISTRY_PASSWORD}" \
        "https://${REGISTRY_URL}/v2/_catalog" --max-time 10 2>/dev/null)

    if echo "$catalog" | grep -q "repositories"; then
        log_pass "可以存取 Registry catalog"
        echo "$catalog" | jq . 2>/dev/null || echo "$catalog"
    else
        log_fail "無法存取 Registry catalog"
    fi

    # 檢查主映像
    log_info "檢查 wooo/momo-pro-system 映像..."
    local tags=$(curl -s -u "${REGISTRY_USER}:${REGISTRY_PASSWORD}" \
        "https://${REGISTRY_URL}/v2/wooo/momo-pro-system/tags/list" --max-time 10 2>/dev/null)

    if echo "$tags" | grep -q "tags"; then
        log_pass "wooo/momo-pro-system 映像存在"
        echo "$tags" | jq . 2>/dev/null || echo "$tags"
    else
        log_warn "wooo/momo-pro-system 映像尚未推送"
    fi
}

# =============================================================================
# 8. 監控腳本檢查
# =============================================================================
check_monitoring_scripts() {
    section "8. 監控腳本檢查"

    # Registry 健康監控
    if [[ -f "scripts/registry_health_monitor.sh" ]]; then
        log_pass "Registry 健康監控腳本存在"
    else
        log_fail "Registry 健康監控腳本不存在"
    fi

    # 部署腳本庫
    if [[ -f "deploy/lib/registry.sh" ]]; then
        log_pass "Registry 部署函數庫存在"
    else
        log_fail "Registry 部署函數庫不存在"
    fi

    # Nginx 配置
    if [[ -f "config/nginx/sites-available/registry" ]]; then
        log_pass "Registry Nginx 配置存在"
    else
        log_warn "Registry Nginx 配置不存在"
    fi

    # Docker Compose
    if [[ -f "docker/registry/docker-compose.yml" ]]; then
        log_pass "Registry docker-compose.yml 存在"
    else
        log_fail "Registry docker-compose.yml 不存在"
    fi
}

# =============================================================================
# 9. 全域 Harbor 引用檢查
# =============================================================================
check_harbor_references() {
    section "9. 全域 Harbor 引用檢查"

    log_info "搜尋所有檔案中的 Harbor 引用..."

    local harbor_files=$(grep -ril "harbor" \
        --include="*.py" \
        --include="*.yaml" \
        --include="*.yml" \
        --include="*.sh" \
        --include="*.html" \
        --include="*.md" \
        . 2>/dev/null | grep -v ".git" | grep -v "node_modules" | grep -v "__pycache__" || true)

    if [[ -z "$harbor_files" ]]; then
        log_pass "無 Harbor 引用存在"
    else
        log_warn "以下檔案仍有 Harbor 引用:"
        echo "$harbor_files" | while read -r file; do
            echo "  - $file"
        done
    fi
}

# =============================================================================
# 總結報告
# =============================================================================
summary() {
    section "驗證報告總結"

    echo ""
    echo -e "✅ ${GREEN}通過${NC}: $PASSED"
    echo -e "❌ ${RED}失敗${NC}: $FAILED"
    echo -e "⚠️  ${YELLOW}警告${NC}: $WARNINGS"
    echo ""

    if [[ $FAILED -eq 0 ]]; then
        echo -e "${GREEN}=============================================="
        echo "  CI/CD 驗證通過！可以進行部署。"
        echo "==============================================${NC}"
        return 0
    else
        echo -e "${RED}=============================================="
        echo "  CI/CD 驗證失敗！請修復上述問題。"
        echo "==============================================${NC}"
        return 1
    fi
}

# =============================================================================
# 主程式
# =============================================================================
main() {
    echo ""
    echo "=============================================="
    echo "  Docker Registry CI/CD 驗證"
    echo "  $(date '+%Y-%m-%d %H:%M:%S')"
    echo "=============================================="

    check_local_env
    check_ssh_connections
    check_registry_service
    check_k8s_services
    check_app_health
    check_cicd_config
    check_registry_images
    check_monitoring_scripts
    check_harbor_references

    summary
}

# 執行
main "$@"
