#!/bin/bash
# Validate and optimize VM YAML configurations
# Ensures quota checks, non-compounded commands, and best practices

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
VM_DIR="${PROJECT_ROOT}/examples/production"

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

log() {
    echo -e "${BLUE}[$(date +'%H:%M:%S')]${NC} $*"
}

log_success() {
    echo -e "${GREEN}[$(date +'%H:%M:%S')] ✅${NC} $*"
}

log_warning() {
    echo -e "${YELLOW}[$(date +'%H:%M:%S')] ⚠️${NC} $*"
}

log_error() {
    echo -e "${RED}[$(date +'%H:%M:%S')] ❌${NC} $*"
}

# Check if YAML file has required fields
check_yaml_structure() {
    local file=$1
    local errors=0
    
    # Check for required fields
    if ! grep -q "kind: ProxmoxVM" "$file"; then
        log_error "$file: Missing 'kind: ProxmoxVM'"
        errors=$((errors + 1))
    fi
    
    if ! grep -q "tenant.sankofa.nexus/id" "$file"; then
        log_warning "$file: Missing tenant label (may be intentional for infrastructure VMs)"
    fi
    
    if ! grep -q "image:" "$file"; then
        log_error "$file: Missing image specification"
        errors=$((errors + 1))
    fi
    
    # Check image format
    if grep -q "image:" "$file"; then
        local image=$(grep "image:" "$file" | head -1 | sed 's/.*image: *"\(.*\)".*/\1/')
        if [[ -z "$image" ]]; then
            log_error "$file: Image specification is empty"
            errors=$((errors + 1))
        fi
    fi
    
    return $errors
}

# Check for compounded commands (should be avoided)
check_compounded_commands() {
    local file=$1
    local warnings=0
    
    # Check for problematic patterns
    if grep -q "systemctl.*&&\|systemctl.*||" "$file"; then
        log_warning "$file: Found compounded systemctl commands (should be separate)"
        warnings=$((warnings + 1))
    fi
    
    # Check for command chains in runcmd
    if grep -A 5 "runcmd:" "$file" | grep -q ".*&&.*"; then
        log_warning "$file: Found command chains with && in runcmd (should be separate list items)"
        warnings=$((warnings + 1))
    fi
    
    # Note: || true is acceptable for non-critical error handling
    # But we should document this
    
    return $warnings
}

# Check for quota check annotations
check_quota_annotations() {
    local file=$1
    local warnings=0
    
    # Check if tenant label exists
    if grep -q "tenant.sankofa.nexus/id" "$file"; then
        local tenant=$(grep "tenant.sankofa.nexus/id" "$file" | sed 's/.*tenant.sankofa.nexus\/id: *"\(.*\)".*/\1/')
        if [[ -n "$tenant" && "$tenant" != "infrastructure" ]]; then
            # For tenant VMs, quota should be checked by controller
            # But we can add annotation for explicit quota check
            if ! grep -q "phoenix.sankofa.nexus/quota-check" "$file"; then
                log_warning "$file: Tenant VM should have quota-check annotation (controller will check automatically)"
            fi
        fi
    fi
    
    return $warnings
}

# Validate image specification
check_image_spec() {
    local file=$1
    local errors=0
    
    if grep -q "image:" "$file"; then
        local image=$(grep "image:" "$file" | head -1 | sed 's/.*image: *"\(.*\)".*/\1/')
        
        # Check for valid image format
        if [[ ! "$image" =~ ^[a-zA-Z0-9._-]+$ ]]; then
            log_error "$file: Invalid image format: $image"
            errors=$((errors + 1))
        fi
        
        # Check for recommended image
        if [[ "$image" != "ubuntu-22.04-cloud" ]]; then
            log_warning "$file: Using non-standard image: $image (recommended: ubuntu-22.04-cloud)"
        fi
    fi
    
    return $errors
}

# Check for best practices
check_best_practices() {
    local file=$1
    local warnings=0
    
    # Check for QEMU guest agent
    if ! grep -q "qemu-guest-agent" "$file"; then
        log_warning "$file: Missing qemu-guest-agent package"
        warnings=$((warnings + 1))
    fi
    
    # Check for guest agent enable/start
    if ! grep -q "systemctl enable qemu-guest-agent" "$file"; then
        log_warning "$file: Missing 'systemctl enable qemu-guest-agent'"
        warnings=$((warnings + 1))
    fi
    
    if ! grep -q "systemctl start qemu-guest-agent" "$file"; then
        log_warning "$file: Missing 'systemctl start qemu-guest-agent'"
        warnings=$((warnings + 1))
    fi
    
    # Check for package verification
    if ! grep -q "Verifying required packages" "$file"; then
        log_warning "$file: Missing package verification step"
        warnings=$((warnings + 1))
    fi
    
    return $warnings
}

# Main validation
main() {
    log "Validating and optimizing VM YAML configurations..."
    echo
    
    local total_files=0
    local total_errors=0
    local total_warnings=0
    
    # Find all YAML files
    while IFS= read -r -d '' file; do
        total_files=$((total_files + 1))
        log "Checking: $file"
        
        local file_errors=0
        local file_warnings=0
        
        check_yaml_structure "$file" || file_errors=$?
        check_compounded_commands "$file" || file_warnings=$?
        check_quota_annotations "$file" || file_warnings=$((file_warnings + $?))
        check_image_spec "$file" || file_errors=$((file_errors + $?))
        check_best_practices "$file" || file_warnings=$((file_warnings + $?))
        
        total_errors=$((total_errors + file_errors))
        total_warnings=$((total_warnings + file_warnings))
        
        if [[ $file_errors -eq 0 && $file_warnings -eq 0 ]]; then
            log_success "$file: All checks passed"
        fi
        echo
    done < <(find "$VM_DIR" -name "*.yaml" -type f -print0)
    
    # Summary
    echo
    log "=== Validation Summary ==="
    echo "Files checked: $total_files"
    echo "Errors: $total_errors"
    echo "Warnings: $total_warnings"
    echo
    
    if [[ $total_errors -eq 0 ]]; then
        log_success "All VM configurations are valid!"
        return 0
    else
        log_error "Found $total_errors errors. Please fix before deployment."
        return 1
    fi
}

main "$@"

