#![allow(
    unused_variables,
    unused_imports,
    clippy::tests_outside_test_module
)]
//! Performance Validation Tests for Rainbow DQN
//!
//! These tests validate that the Rainbow DQN implementation meets
//! the HFT performance requirements of <100us inference latency.
//!
//! Hot-path inference benchmarking is done via the fused CUDA kernel
//! `dqn_forward_only_kernel` directly -- the cold-path forward has been removed.

use std::fmt::Write as _;
use std::time::{Duration, Instant};
use tracing::info;

use super::*;
use ml_core::MLError;

/// Performance test configuration
#[derive(Debug, Clone)]
pub struct PerformanceTestConfig {
    pub max_latency_us: u64,
    pub test_iterations: usize,
}

impl Default for PerformanceTestConfig {
    fn default() -> Self {
        Self {
            max_latency_us: 100,
            test_iterations: 1000,
        }
    }
}

/// Performance test results
#[derive(Debug, Clone)]
pub struct PerformanceResults {
    pub avg_latency_us: f64,
    pub mean_latency_us: f64,
    pub p50_latency_us: f64,
    pub p95_latency_us: f64,
    pub p99_latency_us: f64,
    pub max_latency_us: f64,
    pub min_latency_us: f64,
    pub throughput: f64,
    pub throughput_ops_per_sec: f64,
    pub passed: bool,
    pub meets_target: bool,
}

/// Performance validator for Rainbow `DQN`
#[derive(Debug)]
pub struct RainbowPerformanceValidator {
    config: PerformanceTestConfig,
}

impl RainbowPerformanceValidator {
    pub const fn new(config: PerformanceTestConfig) -> Result<Self, MLError> {
        Ok(Self { config })
    }

    /// Compute performance statistics from latency measurements
    pub fn compute_statistics(&self, mut latencies: Vec<f64>) -> PerformanceStatistics {
        if latencies.is_empty() {
            return PerformanceStatistics::default();
        }

        latencies.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal));
        let count = latencies.len();

        let mean = latencies.iter().sum::<f64>() / count as f64;
        let min = latencies.first().copied().unwrap_or(0.0);
        let max = latencies.last().copied().unwrap_or(0.0);
        // Correct median calculation for even/odd length arrays
        let p50 = if count % 2 == 0 {
            let mid = count / 2;
            let a = latencies.get(mid.saturating_sub(1)).copied().unwrap_or(0.0);
            let b = latencies.get(mid).copied().unwrap_or(0.0);
            (a + b) / 2.0
        } else {
            latencies.get(count / 2).copied().unwrap_or(0.0)
        };
        let p95_idx = ((count as f64 * 0.95) as usize).min(count.saturating_sub(1));
        let p99_idx = ((count as f64 * 0.99) as usize).min(count.saturating_sub(1));
        let p95 = latencies.get(p95_idx).copied().unwrap_or(0.0);
        let p99 = latencies.get(p99_idx).copied().unwrap_or(0.0);

        let meets_target = mean < self.config.max_latency_us as f64;

        PerformanceStatistics {
            mean_latency_us: mean,
            p50_latency_us: p50,
            p95_latency_us: p95,
            p99_latency_us: p99,
            min_latency_us: min,
            max_latency_us: max,
            meets_target,
        }
    }

    /// Generate performance report
    pub fn generate_report(&self, results: &[(String, PerformanceResults)]) -> String {
        let passed_count = results.iter().filter(|(_, r)| r.meets_target).count();
        let total_count = results.len();

        let mut report = format!(
            "Performance Report: {}/{} tests passed\n\n",
            passed_count, total_count
        );

        for (name, result) in results {
            let status = if result.meets_target { "PASS" } else { "FAIL" };
            _ = writeln!(
                report,
                "{} {}: {:.1}us avg (target: {}us)",
                status, name, result.mean_latency_us, self.config.max_latency_us
            );
        }

        report
    }
}

/// Performance statistics structure
#[derive(Debug, Default)]
pub struct PerformanceStatistics {
    pub mean_latency_us: f64,
    pub p50_latency_us: f64,
    pub p95_latency_us: f64,
    pub p99_latency_us: f64,
    pub min_latency_us: f64,
    pub max_latency_us: f64,
    pub meets_target: bool,
}

#[test]
fn test_performance_validator_creation() -> Result<(), MLError> {
    let config = PerformanceTestConfig::default();
    let _validator = RainbowPerformanceValidator::new(config)?;
    Ok(())
}

#[test]
fn test_statistics_computation() -> Result<(), MLError> {
    let config = PerformanceTestConfig::default();
    let validator = RainbowPerformanceValidator::new(config)?;

    let latencies = vec![10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0];
    let stats = validator.compute_statistics(latencies);

    assert_eq!(stats.mean_latency_us, 55.0);
    assert_eq!(stats.p50_latency_us, 55.0);
    assert_eq!(stats.min_latency_us, 10.0);
    assert_eq!(stats.max_latency_us, 100.0);
    assert!(stats.meets_target); // 55us < 100us target, so should meet target
    Ok(())
}

#[test]
fn test_performance_report_generation() -> Result<(), MLError> {
    let config = PerformanceTestConfig::default();
    let validator = RainbowPerformanceValidator::new(config)?;

    let results = vec![
        (
            "test1".to_owned(),
            PerformanceResults {
                avg_latency_us: 50.0,
                mean_latency_us: 50.0,
                p50_latency_us: 45.0,
                p95_latency_us: 80.0,
                p99_latency_us: 95.0,
                max_latency_us: 100.0,
                min_latency_us: 30.0,
                throughput: 20000.0,
                throughput_ops_per_sec: 20000.0,
                passed: true,
                meets_target: true,
            },
        ),
        (
            "test2".to_owned(),
            PerformanceResults {
                avg_latency_us: 150.0,
                mean_latency_us: 150.0,
                p50_latency_us: 140.0,
                p95_latency_us: 200.0,
                p99_latency_us: 250.0,
                max_latency_us: 300.0,
                min_latency_us: 100.0,
                throughput: 6666.0,
                throughput_ops_per_sec: 6666.0,
                passed: false,
                meets_target: false,
            },
        ),
    ];

    let report = validator.generate_report(&results);

    assert!(report.contains("1/2 tests passed"));
    assert!(report.contains("PASS"));
    assert!(report.contains("FAIL"));
    assert!(report.contains("test1"));
    assert!(report.contains("test2"));
    Ok(())
}

// NOTE: Rainbow network performance test removed -- RainbowNetwork cold-path
// forward used Candle types which have been eliminated. Hot-path inference
// benchmarking is done via the fused CUDA kernel `dqn_forward_only_kernel`.
