# Migration Script: Switch to Provider-Agnostic Middleware
# This script safely migrates from hardcoded middleware to provider-agnostic architecture

use ../core/nulib/lib_provisioning/utils/logging.nu *

# Migration script
export def main [
    --dry-run    # Show what would be done without executing
    --force      # Skip confirmation prompts
]: nothing -> nothing {

    log-section "Provider-Agnostic Middleware Migration" "migration"

    if $dry_run {
        log-warning "DRY RUN MODE - No actual changes will be made" "migration"
    }

    # Step 1: Backup current middleware
    let middleware_path = "provisioning/extensions/providers/prov_lib/middleware.nu"
    let backup_path = "provisioning/extensions/providers/prov_lib/middleware_hardcoded.backup"

    if ($middleware_path | path exists) {
        if not $dry_run {
            cp $middleware_path $backup_path
        }
        log-info $"Backup created: ($backup_path)" "migration"
    } else {
        log-error $"Middleware file not found: ($middleware_path)" "migration"
        return
    }

    # Step 2: Check provider adapters exist
    let required_adapters = [
        "provisioning/extensions/providers/aws/provider.nu"
        "provisioning/extensions/providers/upcloud/provider.nu"
        "provisioning/extensions/providers/local/provider.nu"
    ]

    mut missing_adapters = []
    for adapter in $required_adapters {
        if not ($adapter | path exists) {
            $missing_adapters = ($missing_adapters | append $adapter)
        }
    }

    if ($missing_adapters | length) > 0 {
        log-error "Missing required provider adapters:" "migration"
        for adapter in $missing_adapters {
            log-error $"  - ($adapter)" "migration"
        }
        return
    } else {
        log-success "All required provider adapters found" "migration"
    }

    # Step 3: Replace middleware with provider-agnostic version
    let agnostic_middleware = "provisioning/extensions/providers/prov_lib/middleware_provider_agnostic.nu"

    if not ($agnostic_middleware | path exists) {
        log-error $"Provider-agnostic middleware not found: ($agnostic_middleware)" "migration"
        return
    }

    if not $dry_run and ($force or (confirm "Replace middleware with provider-agnostic version?")) {
        cp $agnostic_middleware $middleware_path
        log-success "Middleware replaced with provider-agnostic version" "migration"
    } else if $dry_run {
        log-info $"Would replace ($middleware_path) with ($agnostic_middleware)" "migration"
    } else {
        log-warning "Migration cancelled by user" "migration"
        return
    }

    # Step 4: Test the new middleware
    log-info "Testing new provider-agnostic middleware..." "migration"

    if not $dry_run {
        let test_import_result = (do {
            nu -c "use provisioning/extensions/providers/prov_lib/middleware.nu *; mw_provider_status | length"
        } | complete)

        if $test_import_result.exit_code == 0 {
            log-success "Middleware import test passed" "migration"
        } else {
            log-error $"Middleware test failed: ($test_import_result.stderr)" "migration"
            log-warning "Restoring backup..." "migration"
            cp $backup_path $middleware_path
            return
        }

        let test_registry_result = (do {
            nu -c "use provisioning/core/nulib/lib_provisioning/providers/registry.nu *; init-provider-registry"
        } | complete)

        if $test_registry_result.exit_code == 0 {
            log-success "Provider registry initialization test passed" "migration"
        } else {
            log-error $"Middleware test failed: ($test_registry_result.stderr)" "migration"
            log-warning "Restoring backup..." "migration"
            cp $backup_path $middleware_path
            return
        }
    } else {
        log-info "Would run middleware import and registry tests" "migration"
    }

    # Step 5: Show migration summary
    log-section "Migration Summary" "migration"

    let summary = [
        "✅ Backup created: middleware_hardcoded.backup"
        "✅ Provider adapters validated"
        "✅ Provider-agnostic middleware installed"
        "✅ Middleware tests passed"
        ""
        "🚀 Benefits enabled:"
        "  • No hardcoded provider imports"
        "  • Multi-provider infrastructure support"
        "  • Dynamic provider loading"
        "  • Extensible provider system"
        ""
        "📋 Next steps:"
        "  • Test with existing infrastructure"
        "  • Run: ./provisioning/tools/test-provider-agnostic.nu"
        "  • Update any custom code using old middleware"
    ]

    for line in $summary {
        print $line
    }

    if not $dry_run {
        log-success "Migration completed successfully!" "migration"
    } else {
        log-info "Dry run completed - use --force to execute" "migration"
    }
}

# Confirmation helper
def confirm [message: string]: nothing -> bool {
    print $"($message) (y/N): "
    let response = (input)
    $response == "y" or $response == "Y" or $response == "yes"
}

# Rollback migration
export def rollback []: nothing -> nothing {
    log-section "Rolling back provider-agnostic migration" "migration"

    let middleware_path = "provisioning/extensions/providers/prov_lib/middleware.nu"
    let backup_path = "provisioning/extensions/providers/prov_lib/middleware_hardcoded.backup"

    if ($backup_path | path exists) {
        cp $backup_path $middleware_path
        log-success "Rollback completed - hardcoded middleware restored" "migration"
    } else {
        log-error $"Backup not found: ($backup_path)" "migration"
    }
}

# Show migration status
export def status []: nothing -> nothing {
    log-section "Migration Status Check" "migration"

    let middleware_path = "provisioning/extensions/providers/prov_lib/middleware.nu"
    let backup_path = "provisioning/extensions/providers/prov_lib/middleware_hardcoded.backup"

    # Check if middleware exists
    if ($middleware_path | path exists) {
        # Check if it's the new version by looking for provider-agnostic patterns
        let content = (open $middleware_path)
        if ($content | str contains "dispatch_provider_function") {
            log-success "Provider-agnostic middleware is active" "migration"
        } else {
            log-info "Hardcoded middleware is active" "migration"
        }
    } else {
        log-error "Middleware file not found" "migration"
    }

    # Check backup status
    if ($backup_path | path exists) {
        log-info "Backup available for rollback" "migration"
    } else {
        log-warning "No backup found" "migration"
    }

    # Check provider adapters
    let adapters = [
        "provisioning/extensions/providers/aws/provider.nu"
        "provisioning/extensions/providers/upcloud/provider.nu"
        "provisioning/extensions/providers/local/provider.nu"
    ]

    mut adapter_status = []
    for adapter in $adapters {
        let exists = ($adapter | path exists)
        let provider_name = ($adapter | path dirname | path basename)
        $adapter_status = ($adapter_status | append {
            provider: $provider_name
            adapter_exists: $exists
            status: (if $exists { "✅" } else { "❌" })
        })
    }

    print "Provider Adapter Status:"
    print ($adapter_status | table)
}
