use lazy_static::lazy_static;
/// Quick Runtime Validation - Fast performance check for development
/// Run with: cargo bench --bench quick_runtime_validation
use std::time::{Duration, Instant};
use tokio::runtime::{Builder, Runtime};

lazy_static! {
    static ref SHARED_RUNTIME: Runtime = Runtime::new().unwrap();
    static ref LAZY_RUNTIME: Runtime = Builder::new_multi_thread()
        .worker_threads(4)
        .enable_all()
        .build()
        .unwrap();
}

async fn simulate_cli_operation() -> String {
    // Simulate typical CLI operation: I/O + CPU work
    tokio::time::sleep(Duration::from_micros(50)).await;

    let mut result = String::new();
    for i in 0..50 {
        result.push_str(&format!("data_{}\n", i));
    }

    result
}

fn measure_approach(name: &str, iterations: usize, f: impl Fn() -> String) {
    let start = Instant::now();

    for _ in 0..iterations {
        let _ = f();
    }

    let elapsed = start.elapsed();
    let avg = elapsed.as_micros() as f64 / iterations as f64;

    println!(
        "{:30} | {:8} iterations | {:10.2} µs/op | {:8.2} ms total",
        name,
        iterations,
        avg,
        elapsed.as_secs_f64() * 1000.0
    );
}

fn main() {
    println!("\n╔════════════════════════════════════════════════════════════════════════════╗");
    println!("║         Quick Runtime Validation - Async/Sync Wrapper Performance         ║");
    println!("╚════════════════════════════════════════════════════════════════════════════╝\n");

    let iterations = 100;

    println!("Running {} iterations per approach...\n", iterations);
    println!(
        "{:30} | {:>16} | {:>14} | {:>14}",
        "Approach", "Iterations", "Avg Time", "Total"
    );
    println!("{:-<80}", "");

    // Option A: New runtime per command
    measure_approach("Option A: New Runtime", iterations, || {
        let rt = Runtime::new().unwrap();
        rt.block_on(simulate_cli_operation())
    });

    // Option B: Shared static runtime
    measure_approach("Option B: Shared Runtime", iterations, || {
        SHARED_RUNTIME.block_on(simulate_cli_operation())
    });

    // Option C: Lazy static runtime
    measure_approach("Option C: Lazy Static", iterations, || {
        LAZY_RUNTIME.block_on(simulate_cli_operation())
    });

    println!("\n{:-<80}", "");

    // Performance comparison
    println!("\n📊 Performance Analysis:\n");

    // Measure runtime creation overhead
    let creation_samples = 10;
    let mut creation_times = Vec::new();

    for _ in 0..creation_samples {
        let start = Instant::now();
        let _rt = Runtime::new().unwrap();
        creation_times.push(start.elapsed());
    }

    let avg_creation_time: Duration =
        creation_times.iter().sum::<Duration>() / creation_samples as u32;
    let min_creation = creation_times.iter().min().unwrap();
    let max_creation = creation_times.iter().max().unwrap();

    println!("Runtime Creation Overhead:");
    println!("  Average: {:.2} µs", avg_creation_time.as_micros());
    println!("  Min:     {:.2} µs", min_creation.as_micros());
    println!("  Max:     {:.2} µs", max_creation.as_micros());

    // Calculate overhead percentages
    let new_runtime_total = {
        let start = Instant::now();
        for _ in 0..iterations {
            let rt = Runtime::new().unwrap();
            let _ = rt.block_on(simulate_cli_operation());
        }
        start.elapsed()
    };

    let shared_runtime_total = {
        let start = Instant::now();
        for _ in 0..iterations {
            let _ = SHARED_RUNTIME.block_on(simulate_cli_operation());
        }
        start.elapsed()
    };

    let speedup = new_runtime_total.as_secs_f64() / shared_runtime_total.as_secs_f64();
    let overhead_reduction = (1.0 - (1.0 / speedup)) * 100.0;

    println!("\n⚡ Speedup Analysis:");
    println!("  Shared vs New Runtime: {:.2}x faster", speedup);
    println!("  Overhead Reduction:    {:.1}%", overhead_reduction);

    // CLI Performance Validation
    println!("\n✅ ggen v2.0 CLI Performance Targets:");

    let cli_time_new = new_runtime_total.as_millis() as f64 / iterations as f64;
    let cli_time_shared = shared_runtime_total.as_millis() as f64 / iterations as f64;

    let target_ms = 1000.0; // <1s per command

    println!("  Target: <1000ms per command");
    println!(
        "  Option A (New):    {:.2}ms {}",
        cli_time_new,
        if cli_time_new < target_ms {
            "✓"
        } else {
            "✗"
        }
    );
    println!(
        "  Option B (Shared): {:.2}ms {}",
        cli_time_shared,
        if cli_time_shared < target_ms {
            "✓"
        } else {
            "✗"
        }
    );

    // Memory estimation
    println!("\n💾 Memory Analysis:");
    println!("  Runtime Size (est):      ~1-2 MB");
    println!(
        "  New Runtime per call:    ~{:.1} MB total for {} calls",
        (1.5 * iterations as f64),
        iterations
    );
    println!(
        "  Shared Runtime:          ~1.5 MB total for {} calls",
        iterations
    );
    println!(
        "  Memory Saved:            ~{:.1} MB",
        (1.5 * (iterations - 1) as f64)
    );

    // Recommendation
    println!("\n🎯 Recommendation for ggen v2.0:");
    println!();
    println!("  ┌─────────────────────────────────────────────────────────────┐");
    println!("  │  Use Option C: Lazy Static Runtime                         │");
    println!("  │                                                             │");
    println!("  │  Reasons:                                                   │");
    println!(
        "  │  • {:.1}x faster than creating new runtime per command    │",
        speedup
    );
    println!("  │  • Minimal memory footprint (~1.5MB shared)                │");
    println!("  │  • Thread-safe and simple to implement                     │");
    println!("  │  • Ideal for one-shot CLI commands                         │");
    println!("  │  • No state sharing issues between commands                │");
    println!("  └─────────────────────────────────────────────────────────────┘");
    println!();

    // Implementation example
    println!("📝 Implementation Pattern:");
    println!();
    println!("   use lazy_static::lazy_static;");
    println!("   use tokio::runtime::Runtime;");
    println!();
    println!("   lazy_static! {{");
    println!("       static ref TOKIO_RUNTIME: Runtime = Runtime::new().unwrap();");
    println!("   }}");
    println!();
    println!("   pub fn run_async<F, T>(future: F) -> T");
    println!("   where F: std::future::Future<Output = T>");
    println!("   {{");
    println!("       TOKIO_RUNTIME.block_on(future)");
    println!("   }}");
    println!();

    println!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
    println!("✨ Validation Complete - Ready for v2.0 Migration\n");
}
