#!/bin/bash
set -euo pipefail

# Post-Install Validation Script

ERRORS=0
WARNINGS=0

log() {
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*" >&2
}

error() {
    log "ERROR: $*"
    ((ERRORS++))
}

warning() {
    log "WARNING: $*"
    ((WARNINGS++))
}

success() {
    log "✓ $*"
}

check_kubectl() {
    log "Checking kubectl connectivity..."
    
    if ! kubectl cluster-info &> /dev/null; then
        error "Cannot connect to Kubernetes cluster"
        return 1
    fi
    
    success "Kubernetes cluster is accessible"
    return 0
}

check_namespaces() {
    log "Checking required namespaces..."
    
    local namespaces=(
        "argocd"
        "rancher-system"
        "crossplane-system"
        "vault"
        "monitoring"
        "portal"
        "keycloak"
    )
    
    for ns in "${namespaces[@]}"; do
        if kubectl get namespace "${ns}" &> /dev/null; then
            success "Namespace ${ns} exists"
        else
            error "Namespace ${ns} does not exist"
        fi
    done
}

check_deployments() {
    log "Checking deployments..."
    
    local deployments=(
        "argocd/argocd-server"
        "rancher-system/rancher"
        "crossplane-system/crossplane"
        "vault/vault"
        "monitoring/kube-prometheus-stack"
        "portal/portal"
    )
    
    for deployment in "${deployments[@]}"; do
        IFS='/' read -r namespace name <<< "${deployment}"
        if kubectl get deployment "${name}" -n "${namespace}" &> /dev/null; then
            READY=$(kubectl get deployment "${name}" -n "${namespace}" -o jsonpath='{.status.readyReplicas}')
            DESIRED=$(kubectl get deployment "${name}" -n "${namespace}" -o jsonpath='{.status.replicas}')
            if [ "${READY}" = "${DESIRED}" ] && [ "${READY}" != "0" ]; then
                success "Deployment ${name} in ${namespace} is ready (${READY}/${DESIRED})"
            else
                warning "Deployment ${name} in ${namespace} is not ready (${READY}/${DESIRED})"
            fi
        else
            error "Deployment ${name} in ${namespace} does not exist"
        fi
    done
}

check_argocd() {
    log "Checking ArgoCD..."
    
    if kubectl get deployment argocd-server -n argocd &> /dev/null; then
        # Check if ArgoCD is accessible
        if kubectl port-forward -n argocd svc/argocd-server 8080:443 &> /dev/null &
        then
            sleep 2
            if curl -k -s https://localhost:8080 &> /dev/null; then
                success "ArgoCD server is accessible"
            else
                warning "ArgoCD server may not be fully ready"
            fi
            pkill -f "port-forward.*argocd-server" || true
        fi
    else
        error "ArgoCD server not found"
    fi
}

check_crossplane() {
    log "Checking Crossplane..."
    
    if kubectl get deployment crossplane -n crossplane-system &> /dev/null; then
        # Check if provider is installed
        if kubectl get providerconfig -n crossplane-system &> /dev/null; then
            success "Crossplane provider configs found"
        else
            warning "No Crossplane provider configs found"
        fi
    else
        error "Crossplane not found"
    fi
}

check_proxmox_connectivity() {
    log "Checking Proxmox connectivity (if configured)..."
    
    # This would check if Proxmox sites are reachable via tunnels
    # Implementation depends on your setup
    warning "Proxmox connectivity check not implemented"
}

check_cloudflare_tunnels() {
    log "Checking Cloudflare tunnels..."
    
    # Check if cloudflared processes are running on nodes
    # This is a simplified check
    if command -v cloudflared &> /dev/null; then
        if systemctl is-active --quiet cloudflared-tunnel 2>/dev/null; then
            success "Cloudflare tunnel service is active"
        else
            warning "Cloudflare tunnel service may not be running"
        fi
    else
        warning "cloudflared not found (may not be installed on this node)"
    fi
}

check_storage() {
    log "Checking storage classes..."
    
    if kubectl get storageclass &> /dev/null; then
        DEFAULT_SC=$(kubectl get storageclass -o jsonpath='{.items[?(@.metadata.annotations.storageclass\.kubernetes\.io/is-default-class=="true")].metadata.name}')
        if [ -n "${DEFAULT_SC}" ]; then
            success "Default storage class: ${DEFAULT_SC}"
        else
            warning "No default storage class found"
        fi
    else
        error "Cannot list storage classes"
    fi
}

print_summary() {
    log ""
    log "=== Validation Summary ==="
    log "Errors: ${ERRORS}"
    log "Warnings: ${WARNINGS}"
    log ""
    
    if [ "${ERRORS}" -eq 0 ]; then
        log "✓ All critical checks passed!"
        if [ "${WARNINGS}" -gt 0 ]; then
            log "⚠ Some warnings were found, but installation appears functional"
        fi
        return 0
    else
        log "✗ Some errors were found. Please review and fix them."
        return 1
    fi
}

main() {
    log "Starting post-install validation..."
    log ""
    
    check_kubectl
    check_namespaces
    check_deployments
    check_argocd
    check_crossplane
    check_proxmox_connectivity
    check_cloudflare_tunnels
    check_storage
    
    print_summary
}

main "$@"

