#!/usr/bin/env bash
# Migrate Besu nodes from temporary VM to individual LXC containers
# This script exports data from Docker containers in the VM and imports to LXC containers

set -euo pipefail

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

source "$PROJECT_ROOT/lib/common.sh"
source "$PROJECT_ROOT/lib/proxmox-api.sh" 2>/dev/null || true

# Load configuration
load_config "$PROJECT_ROOT/config/proxmox.conf"
load_config "$PROJECT_ROOT/config/network.conf" || {
    log_warn "network.conf not found, using defaults"
}

# VM Configuration
TEMP_VM_IP="${BESU_TEMP_IP:-192.168.11.90}"
TEMP_VM_DATA="/opt/besu"
SOURCE_PROJECT="${1:-/opt/smom-dbis-138}"

# LXC Container VMIDs
VMID_VALIDATORS_START="${VMID_VALIDATORS_START:-1000}"
VMID_SENTRIES_START="${VMID_SENTRIES_START:-1500}"
VMID_RPC_START="${VMID_RPC_START:-2500}"

VALIDATOR_COUNT="${VALIDATOR_COUNT:-5}"
SENTRY_COUNT="${SENTRY_COUNT:-4}"
RPC_COUNT="${RPC_COUNT:-3}"

log_info "Migrating Besu nodes from temporary VM to LXC containers..."
log_info "Source VM: $TEMP_VM_IP"
log_info "Source data: $TEMP_VM_DATA"

# Check if running on Proxmox host
if ! command_exists pct; then
    error_exit "This script must be run on Proxmox host (pct command not found)"
fi

check_root

# Check if VM is accessible
if ! ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 "root@$TEMP_VM_IP" "echo 'VM accessible'" 2>/dev/null; then
    log_error "Cannot access temporary VM at $TEMP_VM_IP"
    log_info "Please ensure:"
    log_info "1. VM is running"
    log_info "2. SSH access is configured"
    log_info "3. IP address is correct"
    exit 1
fi

# Create temporary directory for migration data
MIGRATION_DIR="/tmp/besu-migration-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$MIGRATION_DIR"
log_info "Migration data directory: $MIGRATION_DIR"

# Function to export data from Docker container
export_docker_data() {
    local container_name="$1"
    local node_type="$2"
    local node_num="$3"
    
    log_info "Exporting data from $container_name..."
    
    # Create export directory
    local export_dir="$MIGRATION_DIR/$node_type-$node_num"
    mkdir -p "$export_dir"
    
    # Export data directory
    ssh "root@$TEMP_VM_IP" "docker exec $container_name tar czf - -C /data/besu ." > "$export_dir/data.tar.gz" || {
        log_warn "Failed to export data from $container_name (may not exist)"
        return 1
    }
    
    # Export config
    ssh "root@$TEMP_VM_IP" "docker exec $container_name tar czf - -C /etc/besu ." > "$export_dir/config.tar.gz" 2>/dev/null || true
    
    # Export keys
    ssh "root@$TEMP_VM_IP" "docker exec $container_name tar czf - -C /keys ." > "$export_dir/keys.tar.gz" 2>/dev/null || true
    
    log_success "Exported data from $container_name"
}

# Function to import data to LXC container
import_lxc_data() {
    local vmid="$1"
    local node_type="$2"
    local node_num="$3"
    
    log_info "Importing data to LXC container $vmid..."
    
    local export_dir="$MIGRATION_DIR/$node_type-$node_num"
    
    if [[ ! -d "$export_dir" ]]; then
        log_warn "Export directory not found: $export_dir"
        return 1
    fi
    
    # Check if container exists
    if ! pct list | grep -q "^\s*$vmid\s"; then
        log_warn "Container $vmid does not exist. Please deploy it first using deploy-besu-nodes.sh"
        return 1
    fi
    
    # Ensure container is running
    if ! pct list | grep -q "^\s*$vmid.*running"; then
        log_info "Starting container $vmid..."
        pct start "$vmid" || {
            log_error "Failed to start container $vmid"
            return 1
        }
        sleep 5
    fi
    
    # Import data
    if [[ -f "$export_dir/data.tar.gz" ]]; then
        log_info "Importing data directory..."
        pct push "$vmid" "$export_dir/data.tar.gz" /tmp/data.tar.gz
        pct exec "$vmid" -- bash -c "mkdir -p /data/besu && cd /data/besu && tar xzf /tmp/data.tar.gz && rm /tmp/data.tar.gz"
        log_success "Imported data directory"
    fi
    
    # Import config
    if [[ -f "$export_dir/config.tar.gz" ]]; then
        log_info "Importing config directory..."
        pct push "$vmid" "$export_dir/config.tar.gz" /tmp/config.tar.gz
        pct exec "$vmid" -- bash -c "mkdir -p /etc/besu && cd /etc/besu && tar xzf /tmp/config.tar.gz && rm /tmp/config.tar.gz"
        log_success "Imported config directory"
    fi
    
    # Import keys
    if [[ -f "$export_dir/keys.tar.gz" ]]; then
        log_info "Importing keys..."
        pct push "$vmid" "$export_dir/keys.tar.gz" /tmp/keys.tar.gz
        pct exec "$vmid" -- bash -c "mkdir -p /data/besu/keys && cd /data/besu/keys && tar xzf /tmp/keys.tar.gz && rm /tmp/keys.tar.gz"
        # Also copy to expected location
        pct exec "$vmid" -- bash -c "cp -r /data/besu/keys/* /etc/besu/ 2>/dev/null || true"
        log_success "Imported keys"
    fi
    
    # Set proper permissions
    pct exec "$vmid" -- bash -c "chown -R besu:besu /data/besu /etc/besu 2>/dev/null || true"
    
    log_success "Imported data to container $vmid"
}

# Export data from all Docker containers
log_info "Step 1: Exporting data from Docker containers..."

# Export validators
for i in $(seq 1 $VALIDATOR_COUNT); do
    export_docker_data "besu-validator-$i" "validator" "$i" || true
done

# Export sentries
for i in $(seq 1 $SENTRY_COUNT); do
    export_docker_data "besu-sentry-$i" "sentry" "$i" || true
done

# Export RPC nodes
for i in $(seq 1 $RPC_COUNT); do
    export_docker_data "besu-rpc-$i" "rpc" "$i" || true
done

log_success "Data export completed"

# Check if LXC containers exist
log_info "Step 2: Checking LXC containers..."
MISSING_CONTAINERS=0

for i in $(seq 0 $((VALIDATOR_COUNT - 1))); do
    vmid=$((VMID_VALIDATORS_START + i))
    if ! pct list | grep -q "^\s*$vmid\s"; then
        log_warn "Container $vmid (validator-$((i+1))) does not exist"
        MISSING_CONTAINERS=$((MISSING_CONTAINERS + 1))
    fi
done

for i in $(seq 0 $((SENTRY_COUNT - 1))); do
    vmid=$((VMID_SENTRIES_START + i))
    if ! pct list | grep -q "^\s*$vmid\s"; then
        log_warn "Container $vmid (sentry-$((i+1))) does not exist"
        MISSING_CONTAINERS=$((MISSING_CONTAINERS + 1))
    fi
done

for i in $(seq 0 $((RPC_COUNT - 1))); do
    vmid=$((VMID_RPC_START + i))
    if ! pct list | grep -q "^\s*$vmid\s"; then
        log_warn "Container $vmid (rpc-$((i+1))) does not exist"
        MISSING_CONTAINERS=$((MISSING_CONTAINERS + 1))
    fi
done

if [[ $MISSING_CONTAINERS -gt 0 ]]; then
    log_error "$MISSING_CONTAINERS containers are missing. Please deploy them first:"
    log_info "cd $PROJECT_ROOT && ./scripts/deployment/deploy-besu-nodes.sh"
    exit 1
fi

log_success "All LXC containers exist"

# Import data to LXC containers
log_info "Step 3: Importing data to LXC containers..."

# Import validators
for i in $(seq 1 $VALIDATOR_COUNT); do
    vmid=$((VMID_VALIDATORS_START + i - 1))
    import_lxc_data "$vmid" "validator" "$i" || log_warn "Failed to import validator-$i"
done

# Import sentries
for i in $(seq 1 $SENTRY_COUNT); do
    vmid=$((VMID_SENTRIES_START + i - 1))
    import_lxc_data "$vmid" "sentry" "$i" || log_warn "Failed to import sentry-$i"
done

# Import RPC nodes
for i in $(seq 1 $RPC_COUNT); do
    vmid=$((VMID_RPC_START + i - 1))
    import_lxc_data "$vmid" "rpc" "$i" || log_warn "Failed to import rpc-$i"
done

log_success "Data import completed"

# Copy genesis and permissions files
log_info "Step 4: Copying shared configuration files..."

if [[ -d "$SOURCE_PROJECT/config" ]]; then
    for i in $(seq 0 $((VALIDATOR_COUNT - 1))); do
        vmid=$((VMID_VALIDATORS_START + i))
        if pct list | grep -q "^\s*$vmid\s"; then
            if [[ -f "$SOURCE_PROJECT/config/genesis.json" ]]; then
                pct push "$vmid" "$SOURCE_PROJECT/config/genesis.json" /etc/besu/genesis.json
            fi
            if [[ -f "$SOURCE_PROJECT/config/static-nodes.json" ]]; then
                pct push "$vmid" "$SOURCE_PROJECT/config/static-nodes.json" /etc/besu/static-nodes.json
            fi
            if [[ -f "$SOURCE_PROJECT/config/permissions-nodes.toml" ]]; then
                pct push "$vmid" "$SOURCE_PROJECT/config/permissions-nodes.toml" /etc/besu/permissions-nodes.toml
            fi
        fi
    done
    
    # Same for sentries and RPC nodes
    for i in $(seq 0 $((SENTRY_COUNT - 1))); do
        vmid=$((VMID_SENTRIES_START + i))
        if pct list | grep -q "^\s*$vmid\s"; then
            [[ -f "$SOURCE_PROJECT/config/genesis.json" ]] && pct push "$vmid" "$SOURCE_PROJECT/config/genesis.json" /etc/besu/genesis.json
            [[ -f "$SOURCE_PROJECT/config/static-nodes.json" ]] && pct push "$vmid" "$SOURCE_PROJECT/config/static-nodes.json" /etc/besu/static-nodes.json
            [[ -f "$SOURCE_PROJECT/config/permissions-nodes.toml" ]] && pct push "$vmid" "$SOURCE_PROJECT/config/permissions-nodes.toml" /etc/besu/permissions-nodes.toml
        fi
    done
    
    for i in $(seq 0 $((RPC_COUNT - 1))); do
        vmid=$((VMID_RPC_START + i))
        if pct list | grep -q "^\s*$vmid\s"; then
            [[ -f "$SOURCE_PROJECT/config/genesis.json" ]] && pct push "$vmid" "$SOURCE_PROJECT/config/genesis.json" /etc/besu/genesis.json
            [[ -f "$SOURCE_PROJECT/config/static-nodes.json" ]] && pct push "$vmid" "$SOURCE_PROJECT/config/static-nodes.json" /etc/besu/static-nodes.json
            [[ -f "$SOURCE_PROJECT/config/permissions-nodes.toml" ]] && pct push "$vmid" "$SOURCE_PROJECT/config/permissions-nodes.toml" /etc/besu/permissions-nodes.toml
        fi
    done
fi

log_success "Shared configuration files copied"

log_success "Migration completed!"
log_info ""
log_info "Next steps:"
log_info "1. Verify services in LXC containers: pct exec <VMID> -- systemctl status besu-validator"
log_info "2. Start services if needed: pct exec <VMID> -- systemctl start besu-validator"
log_info "3. Verify network connectivity and peer connections"
log_info "4. Once verified, you can shut down the temporary VM"
log_info ""
log_info "Migration data is stored in: $MIGRATION_DIR"
log_info "You can remove it after verifying the migration: rm -rf $MIGRATION_DIR"

