#!/usr/bin/env bash
# Migrate containers 1504, 2503, 2504, 6201 from ml110 to pve using thin1 storage

set -euo pipefail

# Configuration
PROXMOX_HOST_ML110="192.168.11.10"
ML110_PASS="L@kers2010"
SOURCE_NODE="ml110"
TARGET_NODE="pve"
TARGET_STORAGE="thin1"

# Containers to migrate
CONTAINERS=(1504 2503 2504 6201)

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

log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
log_header() { echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"; }

# SSH helper
ssh_ml110() {
    sshpass -p "$ML110_PASS" ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=accept-new root@"$PROXMOX_HOST_ML110" "$@" 2>&1
}

# Check if container exists
check_container() {
    local vmid=$1
    ssh_ml110 "pct list | grep -q '^$vmid'" && return 0 || return 1
}

# Get container status
get_container_status() {
    local vmid=$1
    ssh_ml110 "pct status $vmid 2>/dev/null | awk '{print \$2}'" || echo "unknown"
}

# Check if container is on target node
is_on_target() {
    local vmid=$1
    if ssh_ml110 "pvesh get /nodes/$TARGET_NODE/lxc/$vmid/status/current 2>/dev/null | grep -q 'status'"; then
        return 0
    else
        return 1
    fi
}

# Migrate a single container
migrate_container() {
    local vmid=$1
    
    log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    log_info "Migrating container $vmid"
    log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    
    # Check if already on target
    if is_on_target "$vmid"; then
        log_success "Container $vmid is already on $TARGET_NODE"
        return 0
    fi
    
    # Check if container exists
    if ! check_container "$vmid"; then
        log_error "Container $vmid not found on $SOURCE_NODE"
        return 1
    fi
    
    # Get container name
    local name=$(ssh_ml110 "pct list | grep '^$vmid' | awk '{print \$4}'")
    log_info "Container name: $name"
    
    # Get current status
    local status=$(get_container_status "$vmid")
    log_info "Current status: $status"
    
    # Stop container if running
    if [ "$status" == "running" ]; then
        log_info "Stopping container $vmid..."
        ssh_ml110 "pct stop $vmid" || {
            log_warn "pct stop failed, trying graceful shutdown..."
            ssh_ml110 "pvesh create /nodes/$SOURCE_NODE/lxc/$vmid/status/shutdown --timeout 30" || true
        }
        
        # Wait for stop
        log_info "Waiting for container to stop..."
        for i in {1..12}; do
            sleep 2
            status=$(get_container_status "$vmid")
            if [ "$status" == "stopped" ]; then
                log_success "Container stopped"
                break
            fi
            if [ $i -lt 12 ]; then
                log_info "Still stopping... (attempt $i/12)"
            fi
        done
        
        if [ "$status" != "stopped" ]; then
            log_warn "Container may still be running, proceeding anyway..."
        fi
    fi
    
    # Perform migration
    log_info "Migrating container $vmid from $SOURCE_NODE to $TARGET_NODE..."
    log_info "Target storage: $TARGET_STORAGE"
    
    # Use pvesh API to migrate with storage specification
    # pct migrate doesn't support --storage, so we use the API
    log_info "Starting migration (this may take several minutes)..."
    local migrate_output=$(ssh_ml110 "pvesh create /nodes/$SOURCE_NODE/lxc/$vmid/migrate --target $TARGET_NODE --storage $TARGET_STORAGE --online 0" 2>&1)
    local migrate_exit=$?
    
    if [ $migrate_exit -eq 0 ]; then
        log_success "Migration command completed for container $vmid"
        
        # Wait and verify
        log_info "Waiting for migration to complete..."
        local migrated=false
        for i in {1..30}; do
            sleep 5
            
            # Check if container is now on target node
            if is_on_target "$vmid"; then
                local target_status=$(ssh_ml110 "pvesh get /nodes/$TARGET_NODE/lxc/$vmid/status/current 2>/dev/null | jq -r '.status' 2>/dev/null" || echo "unknown")
                log_success "Container $vmid is now on $TARGET_NODE (status: $target_status)"
                migrated=true
                break
            fi
            
            if [ $i -lt 30 ]; then
                log_info "Still migrating... (attempt $i/30, ~$((i*5)) seconds)"
            fi
        done
        
        if [ "$migrated" == "false" ]; then
            log_warn "Migration may still be in progress or failed"
            log_info "Check migration status manually:"
            log_info "  ssh root@$PROXMOX_HOST_ML110 'pvesh get /nodes/$TARGET_NODE/lxc/$vmid/status/current'"
            return 1
        fi
        
        return 0
    else
        log_error "Migration failed for container $vmid"
        log_info "Error output: $migrate_output"
        return 1
    fi
}

# Main execution
main() {
    echo ""
    log_header
    log_info "Proxmox Container Migration to pve"
    log_info "Source: $SOURCE_NODE -> Target: $TARGET_NODE"
    log_info "Target Storage: $TARGET_STORAGE"
    log_header
    echo ""
    
    log_info "Containers to migrate: ${CONTAINERS[*]}"
    echo ""
    
    # Check connectivity
    log_info "Checking connectivity to $SOURCE_NODE..."
    if ! sshpass -p "$ML110_PASS" ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=accept-new root@"$PROXMOX_HOST_ML110" "echo 'connected'" 2>/dev/null; then
        log_error "Cannot connect to $SOURCE_NODE"
        exit 1
    fi
    log_success "Connected to $SOURCE_NODE"
    echo ""
    
    # Verify containers exist
    log_info "Verifying containers exist..."
    local found=0
    for vmid in "${CONTAINERS[@]}"; do
        if check_container "$vmid"; then
            local name=$(ssh_ml110 "pct list | grep '^$vmid' | awk '{print \$4}'")
            local status=$(get_container_status "$vmid")
            log_success "Container $vmid found: $name (status: $status)"
            found=$((found + 1))
        else
            log_warn "Container $vmid not found, skipping..."
        fi
    done
    
    if [ $found -eq 0 ]; then
        log_error "No containers found to migrate"
        exit 1
    fi
    
    echo ""
    
    # Check for non-interactive mode
    if [[ "${NON_INTERACTIVE:-}" != "1" ]] && [[ -t 0 ]]; then
        read -p "Continue with migration? (y/N): " -n 1 -r
        echo ""
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            log_info "Operation cancelled"
            exit 0
        fi
    fi
    
    echo ""
    
    # Migrate each container
    local failed=0
    local succeeded=0
    
    for vmid in "${CONTAINERS[@]}"; do
        if migrate_container "$vmid"; then
            succeeded=$((succeeded + 1))
        else
            failed=$((failed + 1))
        fi
        echo ""
    done
    
    # Summary
    log_header
    log_info "Migration Summary"
    log_header
    echo ""
    log_info "Succeeded: $succeeded"
    log_info "Failed: $failed"
    echo ""
    
    # Final verification
    log_info "Final container locations:"
    for vmid in "${CONTAINERS[@]}"; do
        if is_on_target "$vmid"; then
            local target_status=$(ssh_ml110 "pvesh get /nodes/$TARGET_NODE/lxc/$vmid/status/current 2>/dev/null | jq -r '.status' 2>/dev/null" || echo "unknown")
            log_success "Container $vmid: $TARGET_NODE (status: $target_status)"
        else
            log_warn "Container $vmid: not on $TARGET_NODE"
        fi
    done
    
    echo ""
    
    if [ $failed -eq 0 ]; then
        log_success "All containers migrated successfully!"
        log_info ""
        log_info "Next steps:"
        log_info "  1. Verify containers on pve: ssh root@$PROXMOX_HOST_ML110 'pvesh get /nodes/$TARGET_NODE/lxc'"
        log_info "  2. Start containers if needed: ssh root@192.168.11.11 'pct start <VMID>'"
        exit 0
    else
        log_warn "Some containers failed to migrate"
        exit 1
    fi
}

main "$@"

