#![allow(clippy::unwrap_used, clippy::expect_used)]
//! CUDA Backend Detection and Monitoring Example
//!
//! Demonstrates:
//! - NVIDIA CUDA backend detection via trueno/cuda-monitor
//! - Device information retrieval (name, compute capability, memory)
//! - Real-time GPU metrics monitoring
//! - Integration with entrenar's training infrastructure
//!
//! Run with: cargo run --example cuda_backend --features cuda

use std::time::Instant;

fn main() {
    println!("╔══════════════════════════════════════════════════════════════╗");
    println!("║      CUDA Backend Detection & Monitoring (trueno-gpu)        ║");
    println!("╚══════════════════════════════════════════════════════════════╝\n");

    // 1. Check feature availability
    check_feature_availability();

    // 2. Detect CUDA devices
    detect_cuda_devices();

    // 3. Compare backends
    compare_backends();

    // 4. Show trueno integration
    show_trueno_integration();

    println!("\n╔══════════════════════════════════════════════════════════════╗");
    println!("║                      Demo Complete                            ║");
    println!("╚══════════════════════════════════════════════════════════════╝");
}

fn check_feature_availability() {
    println!("┌─ Feature Availability ──────────────────────────────────────┐");

    #[cfg(feature = "cuda")]
    {
        println!("│ ✅ CUDA feature: ENABLED");
        println!("│    trueno/cuda-monitor is available");
    }

    #[cfg(not(feature = "cuda"))]
    {
        println!("│ ⚠️  CUDA feature: NOT ENABLED");
        println!("│    Run with: cargo run --example cuda_backend --features cuda");
    }

    #[cfg(feature = "gpu")]
    {
        println!("│ ✅ GPU feature: ENABLED (wgpu/WebGPU)");
    }

    #[cfg(not(feature = "gpu"))]
    {
        println!("│ ⚠️  GPU feature: NOT ENABLED");
    }

    println!("│");
    println!("│ Default backend: CPU SIMD (trueno)");
    println!("└──────────────────────────────────────────────────────────────┘\n");
}

fn detect_cuda_devices() {
    println!("┌─ CUDA Device Detection ─────────────────────────────────────┐");

    #[cfg(feature = "cuda")]
    {
        // Try to detect CUDA devices via trueno-gpu
        println!("│ Querying NVIDIA driver via trueno-gpu...");
        println!("│");

        // Check if NVIDIA driver is available
        if std::path::Path::new("/usr/lib/x86_64-linux-gnu/libcuda.so").exists()
            || std::path::Path::new("/usr/lib/libcuda.so").exists()
            || std::env::var("CUDA_PATH").is_ok()
        {
            println!("│ ✅ NVIDIA driver detected");
            println!("│");

            // In a real implementation, this would call trueno_gpu::CudaContext
            // For demo purposes, we show what information would be available
            println!("│ Device Information (via nvidia-smi):");

            // Try to get actual GPU info from nvidia-smi
            if let Ok(output) = std::process::Command::new("nvidia-smi")
                .args([
                    "--query-gpu=name,memory.total,compute_cap",
                    "--format=csv,noheader",
                ])
                .output()
            {
                if output.status.success() {
                    let info = String::from_utf8_lossy(&output.stdout);
                    for (idx, line) in info.lines().enumerate() {
                        let parts: Vec<&str> = line.split(',').map(str::trim).collect();
                        if parts.len() >= 3 {
                            println!("│   GPU {}: {}", idx, parts[0]);
                            println!("│   - Memory: {}", parts[1]);
                            println!("│   - Compute: SM {}", parts[2]);
                        }
                    }
                } else {
                    println!("│   (nvidia-smi query failed)");
                }
            }

            println!("│");
            println!("│ With cuda feature, trueno-gpu provides:");
            println!("│   - Pure Rust PTX generation (no nvcc needed)");
            println!("│   - Runtime CUDA driver loading");
            println!("│   - Device memory management");
            println!("│   - Kernel execution");
        } else {
            println!("│ ⚠️  NVIDIA driver not found");
            println!("│    CUDA feature enabled but no GPU available");
            println!("│    Install NVIDIA driver for CUDA support");
        }
    }

    #[cfg(not(feature = "cuda"))]
    {
        println!("│ CUDA detection requires --features cuda");
        println!("│");
        println!("│ To enable CUDA support:");
        println!("│   cargo run --example cuda_backend --features cuda");
    }

    println!("└──────────────────────────────────────────────────────────────┘\n");
}

fn compare_backends() {
    println!("┌─ Backend Comparison ─────────────────────────────────────────┐");
    println!("│                                                              │");
    println!("│ | Backend  | Feature      | Use Case                    |   │");
    println!("│ |----------|--------------|-----------------------------│   │");
    println!("│ | CPU SIMD | (default)    | General, portable           |   │");
    println!("│ | GPU      | --features gpu  | Cross-platform GPU (wgpu)|   │");
    println!("│ | CUDA     | --features cuda | Max perf on NVIDIA GPUs  |   │");
    println!("│                                                              │");
    println!("│ Performance Expectations:                                    │");
    println!("│   CPU SIMD: 1x (baseline with AVX2/AVX-512/NEON)            │");
    println!("│   GPU:      5-50x (depends on workload, cross-platform)    │");
    println!("│   CUDA:     10-100x (NVIDIA optimized, tensor cores)       │");
    println!("│                                                              │");
    println!("└──────────────────────────────────────────────────────────────┘\n");
}

fn show_trueno_integration() {
    println!("┌─ Trueno Integration ────────────────────────────────────────┐");
    println!("│                                                              │");
    println!("│ entrenar uses trueno for compute acceleration:              │");
    println!("│                                                              │");
    println!("│   trueno v0.8.3                                             │");
    println!("│   ├── CPU SIMD (AVX2, AVX-512, NEON)                        │");
    println!("│   ├── trueno/gpu (wgpu compute shaders)                     │");
    println!("│   └── trueno/cuda-monitor (via trueno-gpu v0.2.0)          │");
    println!("│                                                              │");
    println!("│ Cargo.toml configuration:                                   │");
    println!("│                                                              │");
    println!("│   [dependencies]                                            │");
    println!("│   entrenar = {{ version = \"0.2.8\", features = [\"cuda\"] }}    │");
    println!("│                                                              │");
    println!("│ Or for GPU (wgpu):                                          │");
    println!("│                                                              │");
    println!("│   entrenar = {{ version = \"0.2.8\", features = [\"gpu\"] }}     │");
    println!("│                                                              │");
    println!("└──────────────────────────────────────────────────────────────┘\n");

    // Show a simple benchmark comparing CPU operations
    println!("┌─ Quick SIMD Benchmark ──────────────────────────────────────┐");

    let size = 1_000_000;
    let a: Vec<f32> = (0..size).map(|i| i as f32 * 0.001).collect();
    let b: Vec<f32> = (0..size).map(|i| (size - i) as f32 * 0.001).collect();

    // Dot product benchmark
    let start = Instant::now();
    let _dot: f32 = a.iter().zip(b.iter()).map(|(x, y)| x * y).sum();
    let cpu_time = start.elapsed();

    println!("│ Vector dot product ({size} elements): {cpu_time:?}");
    println!(
        "│ Throughput: {:.2} GFLOPS",
        (2.0 * f64::from(size)) / cpu_time.as_secs_f64() / 1e9
    );
    println!("│");
    println!("│ With CUDA, expect 10-100x improvement on large workloads    │");
    println!("└──────────────────────────────────────────────────────────────┘\n");

    // Show GPU monitoring integration
    #[cfg(feature = "cuda")]
    {
        println!("┌─ GPU Monitoring (Andon System) ──────────────────────────────┐");
        println!("│                                                              │");
        println!("│ With CUDA enabled, entrenar provides:                        │");
        println!("│   - Real-time GPU temperature monitoring                    │");
        println!("│   - Memory utilization tracking                             │");
        println!("│   - Power consumption metrics                               │");
        println!("│   - Andon alerts for thermal throttling                     │");
        println!("│                                                              │");
        println!("│ See: cargo run --example mnist_train_gpu --features cuda    │");
        println!("└──────────────────────────────────────────────────────────────┘\n");
    }
}
