#!/bin/bash
# Comprehensive Deployment Validation for ml110-01
# Validates all prerequisites, configurations, and deployment readiness

set +e  # Don't exit on errors - we want to collect all results

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
DEPLOY_DIR="$PROJECT_ROOT/smom-dbis-138-proxmox"

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

# Status tracking
declare -a PASSED_ITEMS
declare -a FAILED_ITEMS
declare -a WARNING_ITEMS

pass() {
    echo -e "${GREEN}✅${NC} $1"
    PASSED_ITEMS+=("$1")
}

fail() {
    echo -e "${RED}❌${NC} $1"
    FAILED_ITEMS+=("$1")
}

warn() {
    echo -e "${YELLOW}⚠️${NC} $1"
    WARNING_ITEMS+=("$1")
}

info() {
    echo -e "${BLUE}ℹ️${NC} $1"
}

section() {
    echo ""
    echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo -e "${CYAN}$1${NC}"
    echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo ""
}

# Load environment
ENV_FILE="$HOME/.env"
if [ -f "$ENV_FILE" ]; then
    source <(grep -E "^PROXMOX_" "$ENV_FILE" 2>/dev/null | sed 's/^/export /' || true)
fi

TARGET_HOST="${PROXMOX_HOST:-192.168.11.10}"
TARGET_NODE="${PROXMOX_NODE:-ml110-01}"

echo ""
echo -e "${BLUE}╔════════════════════════════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║${NC}     Deployment Validation for ml110-01 (${TARGET_HOST})          ${BLUE}║${NC}"
echo -e "${BLUE}╚════════════════════════════════════════════════════════════════════════╝${NC}"
echo ""

# ============================================================================
# SECTION 1: PREREQUISITES
# ============================================================================

section "1. PREREQUISITES CHECK"

# Check required tools
REQUIRED_TOOLS=("curl" "jq" "git" "bash")
for tool in "${REQUIRED_TOOLS[@]}"; do
    if command -v "$tool" &> /dev/null; then
        VERSION=$($tool --version 2>&1 | head -1 | cut -d' ' -f1-3)
        pass "$tool installed ($VERSION)"
    else
        fail "$tool not found (required)"
    fi
done

# Check deployment directory
if [ -d "$DEPLOY_DIR" ]; then
    pass "Deployment directory exists: $DEPLOY_DIR"
else
    fail "Deployment directory not found: $DEPLOY_DIR"
    exit 1
fi

# ============================================================================
# SECTION 2: PROXMOX CONNECTION
# ============================================================================

section "2. PROXMOX CONNECTION VALIDATION"

if [ -z "${PROXMOX_USER:-}" ] || [ -z "${PROXMOX_TOKEN_NAME:-}" ] || [ -z "${PROXMOX_TOKEN_VALUE:-}" ]; then
    fail "Proxmox credentials not configured in .env"
    info "Required: PROXMOX_USER, PROXMOX_TOKEN_NAME, PROXMOX_TOKEN_VALUE"
else
    pass "Proxmox credentials found in .env"
fi

# Test API connectivity
info "Testing connection to $TARGET_HOST:8006"
API_RESPONSE=$(curl -k -s -w "\n%{http_code}" -m 10 \
    -H "Authorization: PVEAPIToken=${PROXMOX_USER}!${PROXMOX_TOKEN_NAME}=${PROXMOX_TOKEN_VALUE}" \
    "https://${TARGET_HOST}:8006/api2/json/version" 2>&1)

HTTP_CODE=$(echo "$API_RESPONSE" | tail -1)
RESPONSE_BODY=$(echo "$API_RESPONSE" | sed '$d')

if [ "$HTTP_CODE" = "200" ]; then
    VERSION=$(echo "$RESPONSE_BODY" | python3 -c "import sys, json; print(json.load(sys.stdin)['data']['version'])" 2>/dev/null || echo "unknown")
    pass "API connection successful (Proxmox version: $VERSION)"
else
    fail "API connection failed (HTTP $HTTP_CODE)"
    if [ -n "$RESPONSE_BODY" ]; then
        info "Response: $(echo "$RESPONSE_BODY" | head -c 200)"
    fi
fi

# Get node list
info "Retrieving node list..."
NODES_RESPONSE=$(curl -k -s -m 10 \
    -H "Authorization: PVEAPIToken=${PROXMOX_USER}!${PROXMOX_TOKEN_NAME}=${PROXMOX_TOKEN_VALUE}" \
    "https://${TARGET_HOST}:8006/api2/json/nodes" 2>&1)

if echo "$NODES_RESPONSE" | python3 -c "import sys, json; json.load(sys.stdin)['data']" 2>/dev/null; then
    NODE_COUNT=$(echo "$NODES_RESPONSE" | python3 -c "import sys, json; print(len(json.load(sys.stdin)['data']))" 2>/dev/null)
    NODE_NAMES=$(echo "$NODES_RESPONSE" | python3 -c "import sys, json; print(' '.join([n['node'] for n in json.load(sys.stdin)['data']]))" 2>/dev/null)
    pass "Retrieved $NODE_COUNT node(s): $NODE_NAMES"
    
    # Check if target node exists
    if echo "$NODES_RESPONSE" | python3 -c "import sys, json; data=json.load(sys.stdin)['data']; exit(0 if any(n['node']=='${TARGET_NODE}' for n in data) else 1)" 2>/dev/null; then
        pass "Target node '$TARGET_NODE' found"
    else
        FIRST_NODE=$(echo "$NODES_RESPONSE" | python3 -c "import sys, json; print(json.load(sys.stdin)['data'][0]['node'])" 2>/dev/null)
        warn "Target node '$TARGET_NODE' not found, will use: $FIRST_NODE"
        TARGET_NODE="$FIRST_NODE"
    fi
else
    fail "Failed to retrieve nodes"
fi

# ============================================================================
# SECTION 3: STORAGE VALIDATION
# ============================================================================

section "3. STORAGE VALIDATION"

STORAGE_RESPONSE=$(curl -k -s -m 10 \
    -H "Authorization: PVEAPIToken=${PROXMOX_USER}!${PROXMOX_TOKEN_NAME}=${PROXMOX_TOKEN_VALUE}" \
    "https://${TARGET_HOST}:8006/api2/json/nodes/${TARGET_NODE}/storage" 2>&1)

if echo "$STORAGE_RESPONSE" | python3 -c "import sys, json; json.load(sys.stdin)['data']" 2>/dev/null; then
    STORAGE_COUNT=$(echo "$STORAGE_RESPONSE" | python3 -c "import sys, json; print(len(json.load(sys.stdin)['data']))" 2>/dev/null)
    pass "Found $STORAGE_COUNT storage pool(s)"
    
    # Check for container storage
    CONTAINER_STORAGE=$(echo "$STORAGE_RESPONSE" | python3 -c "import sys, json; data=json.load(sys.stdin)['data']; result=[s['storage'] for s in data if 'rootdir' in s.get('content', '').split(',')]; print(result[0] if result else '')" 2>/dev/null)
    if [ -n "$CONTAINER_STORAGE" ]; then
        pass "Container storage found: $CONTAINER_STORAGE"
    else
        fail "No container storage (rootdir) found"
    fi
    
    # Check for template storage
    TEMPLATE_STORAGE=$(echo "$STORAGE_RESPONSE" | python3 -c "import sys, json; data=json.load(sys.stdin)['data']; result=[s['storage'] for s in data if 'vztmpl' in s.get('content', '').split(',')]; print(result[0] if result else '')" 2>/dev/null)
    if [ -n "$TEMPLATE_STORAGE" ]; then
        pass "Template storage found: $TEMPLATE_STORAGE"
    else
        warn "No template storage (vztmpl) found"
    fi
else
    fail "Failed to retrieve storage information"
fi

# ============================================================================
# SECTION 4: TEMPLATE VALIDATION
# ============================================================================

section "4. LXC TEMPLATE VALIDATION"

if [ -n "$TEMPLATE_STORAGE" ]; then
    info "Checking templates on storage: $TEMPLATE_STORAGE"
    TEMPLATES_RESPONSE=$(curl -k -s -m 10 \
        -H "Authorization: PVEAPIToken=${PROXMOX_USER}!${PROXMOX_TOKEN_NAME}=${PROXMOX_TOKEN_VALUE}" \
        "https://${TARGET_HOST}:8006/api2/json/nodes/${TARGET_NODE}/storage/${TEMPLATE_STORAGE}/content?content=vztmpl" 2>&1)
    
    if echo "$TEMPLATES_RESPONSE" | python3 -c "import sys, json; json.load(sys.stdin)['data']" 2>/dev/null; then
        TEMPLATE_COUNT=$(echo "$TEMPLATES_RESPONSE" | python3 -c "import sys, json; print(len(json.load(sys.stdin)['data']))" 2>/dev/null)
        pass "Found $TEMPLATE_COUNT template(s)"
        
        # Check for Debian 12 template
        DEBIAN_TEMPLATE=$(echo "$TEMPLATES_RESPONSE" | python3 -c "import sys, json; data=json.load(sys.stdin)['data']; result=[t['volid'] for t in data if 'debian-12' in t.get('volid', '')]; print(result[0] if result else '')" 2>/dev/null)
        if [ -n "$DEBIAN_TEMPLATE" ]; then
            pass "Debian 12 template found: $DEBIAN_TEMPLATE"
        else
            fail "Debian 12 template not found (required)"
            info "Available templates:"
            echo "$TEMPLATES_RESPONSE" | python3 -c "import sys, json; [print('  -', t['volid']) for t in json.load(sys.stdin)['data'][:10]]" 2>/dev/null
        fi
    else
        warn "Could not retrieve template list"
    fi
else
    warn "Cannot check templates - no template storage configured"
fi

# ============================================================================
# SECTION 5: CONFIGURATION FILES
# ============================================================================

section "5. CONFIGURATION FILES VALIDATION"

CONFIG_DIR="$DEPLOY_DIR/config"
if [ -d "$CONFIG_DIR" ]; then
    pass "Config directory exists: $CONFIG_DIR"
    
    # Check proxmox.conf
    if [ -f "$CONFIG_DIR/proxmox.conf" ]; then
        pass "proxmox.conf exists"
        source "$CONFIG_DIR/proxmox.conf" 2>/dev/null || true
        
        if [ -n "${PROXMOX_HOST:-}" ]; then
            if [ "$PROXMOX_HOST" = "$TARGET_HOST" ]; then
                pass "PROXMOX_HOST configured correctly: $PROXMOX_HOST"
            elif [ "$PROXMOX_HOST" = "proxmox.example.com" ]; then
                warn "PROXMOX_HOST still set to example value"
            else
                warn "PROXMOX_HOST mismatch: $PROXMOX_HOST (expected: $TARGET_HOST)"
            fi
        else
            fail "PROXMOX_HOST not set in proxmox.conf"
        fi
        
        [ -n "${PROXMOX_NODE:-}" ] && pass "PROXMOX_NODE configured: $PROXMOX_NODE" || warn "PROXMOX_NODE not set"
        [ -n "${PROXMOX_STORAGE:-}" ] && pass "PROXMOX_STORAGE configured: $PROXMOX_STORAGE" || warn "PROXMOX_STORAGE not set"
        [ -n "${CONTAINER_OS_TEMPLATE:-}" ] && pass "CONTAINER_OS_TEMPLATE configured: $CONTAINER_OS_TEMPLATE" || warn "CONTAINER_OS_TEMPLATE not set"
    else
        if [ -f "$CONFIG_DIR/proxmox.conf.example" ]; then
            fail "proxmox.conf not found - copy from proxmox.conf.example and configure"
        else
            fail "proxmox.conf not found"
        fi
    fi
    
    # Check network.conf
    if [ -f "$CONFIG_DIR/network.conf" ]; then
        pass "network.conf exists"
        source "$CONFIG_DIR/network.conf" 2>/dev/null || true
        [ -n "${SUBNET_BASE:-}" ] && pass "SUBNET_BASE configured: $SUBNET_BASE" || warn "SUBNET_BASE not set"
        [ -n "${GATEWAY:-}" ] && pass "GATEWAY configured: $GATEWAY" || warn "GATEWAY not set"
    else
        if [ -f "$CONFIG_DIR/network.conf.example" ]; then
            warn "network.conf not found (example exists)"
        else
            warn "network.conf not found"
        fi
    fi
else
    fail "Config directory not found: $CONFIG_DIR"
fi

# ============================================================================
# SECTION 6: DEPLOYMENT SCRIPTS
# ============================================================================

section "6. DEPLOYMENT SCRIPTS VALIDATION"

SCRIPTS_DIR="$DEPLOY_DIR/scripts/deployment"
if [ -d "$SCRIPTS_DIR" ]; then
    pass "Deployment scripts directory exists"
    
    REQUIRED_SCRIPTS=(
        "deploy-all.sh"
        "deploy-besu-nodes.sh"
        "deploy-services.sh"
        "deploy-hyperledger-services.sh"
        "deploy-monitoring.sh"
        "deploy-explorer.sh"
    )
    
    for script in "${REQUIRED_SCRIPTS[@]}"; do
        SCRIPT_PATH="$SCRIPTS_DIR/$script"
        if [ -f "$SCRIPT_PATH" ]; then
            if [ -x "$SCRIPT_PATH" ]; then
                pass "$script exists and is executable"
                # Check syntax
                if bash -n "$SCRIPT_PATH" 2>&1 | grep -q "error"; then
                    fail "$script has syntax errors"
                fi
            else
                warn "$script exists but is not executable"
            fi
        else
            warn "$script not found"
        fi
    done
else
    fail "Deployment scripts directory not found: $SCRIPTS_DIR"
fi

# Check libraries
LIB_DIR="$DEPLOY_DIR/lib"
[ -f "$LIB_DIR/common.sh" ] && pass "common.sh library exists" || fail "common.sh library not found"
[ -f "$LIB_DIR/proxmox-api.sh" ] && pass "proxmox-api.sh library exists" || warn "proxmox-api.sh library not found"

# ============================================================================
# SECTION 7: INSTALLATION SCRIPTS
# ============================================================================

section "7. INSTALLATION SCRIPTS VALIDATION"

INSTALL_DIR="$DEPLOY_DIR/install"
if [ -d "$INSTALL_DIR" ]; then
    pass "Install scripts directory exists"
    
    REQUIRED_INSTALL_SCRIPTS=(
        "besu-validator-install.sh"
        "besu-sentry-install.sh"
        "besu-rpc-install.sh"
        "oracle-publisher-install.sh"
        "ccip-monitor-install.sh"
        "keeper-install.sh"
        "monitoring-stack-install.sh"
        "blockscout-install.sh"
    )
    
    for script in "${REQUIRED_INSTALL_SCRIPTS[@]}"; do
        [ -f "$INSTALL_DIR/$script" ] && pass "$script exists" || warn "$script not found"
    done
else
    fail "Install scripts directory not found: $INSTALL_DIR"
fi

# ============================================================================
# SECTION 8: RESOURCE REQUIREMENTS
# ============================================================================

section "8. RESOURCE REQUIREMENTS VALIDATION"

# Load config if available
if [ -f "$CONFIG_DIR/proxmox.conf" ]; then
    source "$CONFIG_DIR/proxmox.conf" 2>/dev/null || true
    
    # Estimate resources
    VALIDATOR_COUNT="${VALIDATORS_COUNT:-4}"
    SENTRY_COUNT="${SENTRIES_COUNT:-3}"
    RPC_COUNT="${RPC_COUNT:-3}"
    
    ESTIMATED_MEMORY=$(( (VALIDATOR_MEMORY * VALIDATOR_COUNT) + (SENTRY_MEMORY * SENTRY_COUNT) + (RPC_MEMORY * RPC_COUNT) + MONITORING_MEMORY ))
    ESTIMATED_DISK=$(( (VALIDATOR_DISK * VALIDATOR_COUNT) + (SENTRY_DISK * SENTRY_COUNT) + (RPC_DISK * RPC_COUNT) + MONITORING_DISK ))
    
    info "Estimated requirements:"
    info "  Memory: ~$((ESTIMATED_MEMORY / 1024))GB"
    info "  Disk: ~${ESTIMATED_DISK}GB"
    
    # Get node resources
    NODE_STATUS=$(curl -k -s -m 10 \
        -H "Authorization: PVEAPIToken=${PROXMOX_USER}!${PROXMOX_TOKEN_NAME}=${PROXMOX_TOKEN_VALUE}" \
        "https://${TARGET_HOST}:8006/api2/json/nodes/${TARGET_NODE}/status" 2>&1)
    
    if echo "$NODE_STATUS" | python3 -c "import sys, json; json.load(sys.stdin)['data']" 2>/dev/null; then
        NODE_MEMORY=$(echo "$NODE_STATUS" | python3 -c "import sys, json; print(json.load(sys.stdin)['data']['memory']['total'])" 2>/dev/null || echo "0")
        NODE_FREE_MEMORY=$(echo "$NODE_STATUS" | python3 -c "import sys, json; print(json.load(sys.stdin)['data']['memory']['free'])" 2>/dev/null || echo "0")
        
        if [ "$NODE_MEMORY" != "0" ] && [ -n "$NODE_MEMORY" ]; then
            MEMORY_GB=$((NODE_MEMORY / 1024 / 1024 / 1024))
            FREE_MEMORY_GB=$((NODE_FREE_MEMORY / 1024 / 1024 / 1024))
            info "Node resources: ${MEMORY_GB}GB total, ${FREE_MEMORY_GB}GB free"
            
            if [ $FREE_MEMORY_GB -ge $((ESTIMATED_MEMORY / 1024)) ]; then
                pass "Sufficient memory available"
            else
                warn "Limited free memory: need ~$((ESTIMATED_MEMORY / 1024))GB, have ${FREE_MEMORY_GB}GB"
            fi
        fi
    fi
fi

# ============================================================================
# SECTION 9: EXISTING CONTAINERS
# ============================================================================

section "9. EXISTING CONTAINERS CHECK"

CONTAINERS_RESPONSE=$(curl -k -s -m 10 \
    -H "Authorization: PVEAPIToken=${PROXMOX_USER}!${PROXMOX_TOKEN_NAME}=${PROXMOX_TOKEN_VALUE}" \
    "https://${TARGET_HOST}:8006/api2/json/nodes/${TARGET_NODE}/lxc" 2>&1)

if echo "$CONTAINERS_RESPONSE" | python3 -c "import sys, json; json.load(sys.stdin)['data']" 2>/dev/null; then
    EXISTING_COUNT=$(echo "$CONTAINERS_RESPONSE" | python3 -c "import sys, json; print(len(json.load(sys.stdin)['data']))" 2>/dev/null)
    if [ "$EXISTING_COUNT" -gt 0 ]; then
        info "Found $EXISTING_COUNT existing container(s)"
        
        # Check for VMID conflicts
        EXPECTED_VMIDS=(106 107 108 109 110 111 112 115 116 117 120 121 122 130 140 150 151 152 153)
        CONFLICTS=$(echo "$CONTAINERS_RESPONSE" | python3 -c "
import sys, json
data = json.load(sys.stdin)['data']
existing = [c['vmid'] for c in data]
expected = [106, 107, 108, 109, 110, 111, 112, 115, 116, 117, 120, 121, 122, 130, 140, 150, 151, 152, 153]
conflicts = [v for v in expected if v in existing]
print(' '.join(map(str, conflicts)))" 2>/dev/null)
        
        if [ -n "$CONFLICTS" ]; then
            warn "VMID conflicts: $CONFLICTS (containers already exist)"
        else
            pass "No VMID conflicts detected"
        fi
    else
        pass "No existing containers (clean slate)"
    fi
else
    warn "Could not retrieve container list"
fi

# ============================================================================
# SUMMARY
# ============================================================================

section "VALIDATION SUMMARY"

TOTAL_PASSED=${#PASSED_ITEMS[@]}
TOTAL_FAILED=${#FAILED_ITEMS[@]}
TOTAL_WARNINGS=${#WARNING_ITEMS[@]}

echo -e "${CYAN}Results:${NC}"
echo -e "  ${GREEN}Passed:${NC}  $TOTAL_PASSED"
echo -e "  ${RED}Failed:${NC}  $TOTAL_FAILED"
echo -e "  ${YELLOW}Warnings:${NC} $TOTAL_WARNINGS"
echo ""

if [ $TOTAL_FAILED -eq 0 ]; then
    echo -e "${GREEN}✅ Deployment validation PASSED${NC}"
    echo ""
    echo "Next steps:"
    echo "  1. Review and update configuration files in $CONFIG_DIR/"
    echo "  2. Run deployment: cd $DEPLOY_DIR && ./scripts/deployment/deploy-all.sh"
    exit 0
else
    echo -e "${RED}❌ Deployment validation FAILED${NC}"
    echo ""
    echo "Critical issues found. Please fix the failures above before deployment."
    exit 1
fi

