#!/bin/bash
# verify-provider-deployment.sh
# Verifies Crossplane provider deployment and configuration

set -euo pipefail

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

# Configuration
NAMESPACE="${NAMESPACE:-crossplane-system}"
PROVIDER_NAME="crossplane-provider-proxmox"
PROVIDER_CONFIG_NAME="proxmox-provider-config"

log() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

error() {
    echo -e "${RED}[ERROR]${NC} $1" >&2
}

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

info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

check_kubectl() {
    if ! command -v kubectl &> /dev/null; then
        error "kubectl is required but not installed"
        return 1
    fi
    
    if ! kubectl cluster-info &> /dev/null; then
        error "Cannot connect to Kubernetes cluster"
        return 1
    fi
    
    return 0
}

check_crds() {
    log "Checking CRDs..."
    
    local crds=(
        "proxmoxvms.proxmox.sankofa.nexus"
        "proxmoxvmscalesets.proxmox.sankofa.nexus"
        "providerconfigs.proxmox.sankofa.nexus"
    )
    
    local all_ok=true
    for crd in "${crds[@]}"; do
        if kubectl get crd "${crd}" &> /dev/null; then
            log "  ✓ CRD exists: ${crd}"
        else
            error "  ✗ CRD missing: ${crd}"
            all_ok=false
        fi
    done
    
    return $([ "$all_ok" = true ] && echo 0 || echo 1)
}

check_provider_deployment() {
    log "Checking provider deployment..."
    
    if kubectl get deployment "${PROVIDER_NAME}" -n "${NAMESPACE}" &> /dev/null; then
        log "  ✓ Deployment exists: ${PROVIDER_NAME}"
        
        # Check replicas
        local desired=$(kubectl get deployment "${PROVIDER_NAME}" -n "${NAMESPACE}" -o jsonpath='{.spec.replicas}')
        local ready=$(kubectl get deployment "${PROVIDER_NAME}" -n "${NAMESPACE}" -o jsonpath='{.status.readyReplicas}')
        
        if [ "$desired" = "$ready" ] && [ "$ready" != "0" ]; then
            log "  ✓ Deployment ready: ${ready}/${desired} replicas"
        else
            warn "  ⚠ Deployment not ready: ${ready}/${desired} replicas"
            return 1
        fi
    else
        error "  ✗ Deployment missing: ${PROVIDER_NAME}"
        return 1
    fi
    
    return 0
}

check_provider_pod() {
    log "Checking provider pod..."
    
    local pod=$(kubectl get pod -n "${NAMESPACE}" -l app="${PROVIDER_NAME}" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
    
    if [ -z "$pod" ]; then
        error "  ✗ No provider pod found"
        return 1
    fi
    
    log "  ✓ Pod found: ${pod}"
    
    # Check pod status
    local phase=$(kubectl get pod "${pod}" -n "${NAMESPACE}" -o jsonpath='{.status.phase}')
    if [ "$phase" = "Running" ]; then
        log "  ✓ Pod status: ${phase}"
    else
        warn "  ⚠ Pod status: ${phase}"
        return 1
    fi
    
    # Check for errors in logs
    local error_count=$(kubectl logs "${pod}" -n "${NAMESPACE}" --tail=50 2>&1 | grep -i "error\|fatal\|panic" | wc -l)
    if [ "$error_count" -gt 0 ]; then
        warn "  ⚠ Found ${error_count} error(s) in recent logs"
        info "  View logs: kubectl logs ${pod} -n ${NAMESPACE}"
    else
        log "  ✓ No errors in recent logs"
    fi
    
    return 0
}

check_provider_config() {
    log "Checking ProviderConfig..."
    
    if kubectl get providerconfig "${PROVIDER_CONFIG_NAME}" &> /dev/null; then
        log "  ✓ ProviderConfig exists: ${PROVIDER_CONFIG_NAME}"
        
        # Check status
        local status=$(kubectl get providerconfig "${PROVIDER_CONFIG_NAME}" -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' 2>/dev/null)
        if [ "$status" = "True" ]; then
            log "  ✓ ProviderConfig status: Ready"
        else
            warn "  ⚠ ProviderConfig status: ${status:-Unknown}"
            return 1
        fi
    else
        error "  ✗ ProviderConfig missing: ${PROVIDER_CONFIG_NAME}"
        return 1
    fi
    
    return 0
}

check_secret() {
    log "Checking credentials secret..."
    
    local secret_name=$(kubectl get providerconfig "${PROVIDER_CONFIG_NAME}" -o jsonpath='{.spec.credentials.secretRef.name}' 2>/dev/null)
    local secret_namespace=$(kubectl get providerconfig "${PROVIDER_CONFIG_NAME}" -o jsonpath='{.spec.credentials.secretRef.namespace}' 2>/dev/null)
    
    if [ -z "$secret_name" ]; then
        warn "  ⚠ No secret reference found in ProviderConfig"
        return 1
    fi
    
    if kubectl get secret "${secret_name}" -n "${secret_namespace:-${NAMESPACE}}" &> /dev/null; then
        log "  ✓ Secret exists: ${secret_name} (namespace: ${secret_namespace:-${NAMESPACE}})"
    else
        error "  ✗ Secret missing: ${secret_name}"
        return 1
    fi
    
    return 0
}

show_provider_info() {
    info ""
    info "Provider Information:"
    info "===================="
    
    local pod=$(kubectl get pod -n "${NAMESPACE}" -l app="${PROVIDER_NAME}" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
    
    if [ -n "$pod" ]; then
        info "Pod: ${pod}"
        info "Namespace: ${NAMESPACE}"
        info ""
        info "Recent logs (last 10 lines):"
        kubectl logs "${pod}" -n "${NAMESPACE}" --tail=10 2>&1 | sed 's/^/  /'
    fi
}

main() {
    echo ""
    echo "╔══════════════════════════════════════════════════════════════╗"
    echo "║      Crossplane Proxmox Provider - Deployment Check        ║"
    echo "╚══════════════════════════════════════════════════════════════╝"
    echo ""
    
    if ! check_kubectl; then
        exit 1
    fi
    
    local errors=0
    
    check_crds || ((errors++))
    echo ""
    check_provider_deployment || ((errors++))
    echo ""
    check_provider_pod || ((errors++))
    echo ""
    check_provider_config || ((errors++))
    echo ""
    check_secret || ((errors++))
    echo ""
    
    if [ $errors -eq 0 ]; then
        log "✓ All checks passed!"
        show_provider_info
        echo ""
        log "Provider is ready to use!"
    else
        error "✗ Found ${errors} issue(s)"
        echo ""
        warn "Review the errors above and fix them before proceeding"
        show_provider_info
        exit 1
    fi
}

main "$@"

