//! Comprehensive latency validation tool for Trading Service
//!
//! This binary runs comprehensive performance tests to validate that the trading
//! service meets sub-50μs latency targets under various conditions.

use anyhow::{Context, Result};
use clap::{Arg, Command};
use tracing::{error, info, warn};

use trading_service::{
    latency_recorder::LATENCY_RECORDER,
    soak_test::{SoakTestConfig, SoakTestRunner},
};

#[tokio::main]
async fn main() -> Result<()> {
    // Initialize logging
    tracing_subscriber::fmt()
        .with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
        .init();

    info!("🚀 Foxhunt Trading Service - Sub-50μs Latency Validator");
    info!("================================================");

    let matches = Command::new("latency_validator")
        .version("1.0")
        .about("Validates Trading Service sub-50μs latency targets")
        .arg(
            Arg::new("test-type")
                .short('t')
                .long("test")
                .value_parser(["quick", "comprehensive", "custom"])
                .default_value("quick")
                .help("Type of test to run"),
        )
        .arg(
            Arg::new("iterations")
                .short('i')
                .long("iterations")
                .value_parser(clap::value_parser!(usize))
                .default_value("100000")
                .help("Number of iterations (for custom test)"),
        )
        .arg(
            Arg::new("concurrency")
                .short('c')
                .long("concurrency")
                .value_parser(clap::value_parser!(usize))
                .default_value("100")
                .help("Concurrent operations (for custom test)"),
        )
        .arg(
            Arg::new("duration")
                .short('d')
                .long("duration")
                .value_parser(clap::value_parser!(u64))
                .default_value("60")
                .help("Test duration in seconds (for custom test)"),
        )
        .arg(
            Arg::new("target")
                .long("target")
                .value_parser(clap::value_parser!(f64))
                .default_value("50.0")
                .help("Target P99 latency in microseconds"),
        )
        .get_matches();

    let test_type = matches
        .get_one::<String>("test-type")
        .context("Failed to get test-type argument")?;
    let target_latency = *matches
        .get_one::<f64>("target")
        .context("Failed to get target latency argument")?;

    info!("Test Configuration:");
    info!("  Test Type: {}", test_type);
    info!("  Target P99 Latency: {}μs", target_latency);

    let success = match test_type.as_str() {
        "quick" => run_quick_test(target_latency).await?,
        "comprehensive" => run_comprehensive_test(target_latency).await?,
        "custom" => {
            let iterations = *matches
                .get_one::<usize>("iterations")
                .context("Failed to get iterations argument")?;
            let concurrency = *matches
                .get_one::<usize>("concurrency")
                .context("Failed to get concurrency argument")?;
            let duration = *matches
                .get_one::<u64>("duration")
                .context("Failed to get duration argument")?;
            run_custom_test(target_latency, iterations, concurrency, duration).await?
        },
        _ => {
            error!("Invalid test type: {}", test_type);
            return Ok(());
        },
    };

    // Final report
    info!("================================================");
    if success {
        info!("✅ SUCCESS: All latency targets met!");
        info!(
            "   Trading Service is ready for sub-{}μs production deployment",
            target_latency
        );
    } else {
        warn!("❌ FAILURE: Some latency targets not met");
        warn!("   Review the detailed results above for optimization opportunities");
    }
    info!("================================================");

    Ok(())
}

/// Run quick validation test (30 seconds, moderate load)
async fn run_quick_test(target_latency: f64) -> Result<bool> {
    info!("🚀 Running Quick Validation Test (30s, moderate load)...");
    info!("   - 10,000 iterations maximum");
    info!("   - 50 concurrent operations");
    info!("   - 30 second duration");

    let config = SoakTestConfig {
        iterations: 10_000,
        duration_seconds: 30,
        concurrency: 50,
        target_p99_us: target_latency,
        warmup_iterations: 500,
    };

    let runner = SoakTestRunner::new(config);
    let results = runner
        .run_soak_test()
        .await
        .context("Failed to run quick soak test")?;

    generate_summary_report(&results);
    Ok(results.target_met)
}

/// Run comprehensive validation test (5 minutes, high load)
async fn run_comprehensive_test(target_latency: f64) -> Result<bool> {
    info!("🚀 Running Comprehensive Validation Test (5 minutes, high load)...");
    info!("   - 1,000,000 iterations maximum");
    info!("   - 200 concurrent operations");
    info!("   - 300 second (5 minute) duration");

    let config = SoakTestConfig {
        iterations: 1_000_000,
        duration_seconds: 300,
        concurrency: 200,
        target_p99_us: target_latency,
        warmup_iterations: 5_000,
    };

    let runner = SoakTestRunner::new(config);
    let results = runner
        .run_soak_test()
        .await
        .context("Failed to run comprehensive soak test")?;

    generate_summary_report(&results);
    Ok(results.target_met)
}

/// Run custom validation test with user-specified parameters
async fn run_custom_test(
    target_latency: f64,
    iterations: usize,
    concurrency: usize,
    duration: u64,
) -> Result<bool> {
    info!("🚀 Running Custom Validation Test...");
    info!("   - {} iterations maximum", iterations);
    info!("   - {} concurrent operations", concurrency);
    info!("   - {} second duration", duration);

    let config = SoakTestConfig {
        iterations,
        duration_seconds: duration,
        concurrency,
        target_p99_us: target_latency,
        warmup_iterations: std::cmp::min(iterations / 10, 5_000),
    };

    let runner = SoakTestRunner::new(config);
    let results = runner
        .run_soak_test()
        .await
        .context("Failed to run custom soak test")?;

    generate_summary_report(&results);
    Ok(results.target_met)
}

/// Generate comprehensive summary report
fn generate_summary_report(results: &trading_service::soak_test::SoakTestResults) {
    info!("📊 PERFORMANCE VALIDATION SUMMARY");
    info!("================================");

    // Operations summary
    info!("Operations Performance:");
    info!("  Total Operations: {}", results.total_operations);
    info!(
        "  Success Rate: {:.2}% ({}/{})",
        (results.successful_operations as f64 / results.total_operations as f64) * 100.0,
        results.successful_operations,
        results.total_operations
    );
    info!("  Throughput: {:.0} ops/sec", results.operations_per_second);
    info!(
        "  Test Duration: {:.1}s",
        results.test_duration.as_secs_f64()
    );

    // Latency target summary
    info!("Latency Target Analysis:");
    info!(
        "  Target P99 Latency: {:.1}μs",
        results.config.target_p99_us
    );
    if results.target_met {
        info!("  🎯 OVERALL RESULT: ✅ ALL TARGETS MET");
    } else {
        info!("  🎯 OVERALL RESULT: ❌ SOME TARGETS NOT MET");
    }

    if !results.categories_passed.is_empty() {
        info!(
            "  ✅ Passed Categories ({}):",
            results.categories_passed.len()
        );
        for category in &results.categories_passed {
            info!("     - {}", category);
        }
    }

    if !results.categories_failed.is_empty() {
        info!(
            "  ❌ Failed Categories ({}):",
            results.categories_failed.len()
        );
        for category in &results.categories_failed {
            info!("     - {}", category);
        }
    }

    // Detailed latency breakdown
    info!("Detailed Latency Breakdown:");
    let report = LATENCY_RECORDER.generate_report();
    for category_report in &report.categories {
        let stats = &category_report.stats;
        let status = if category_report.target_met_50us {
            "✅"
        } else {
            "❌"
        };

        info!(
            "  {} {} ({} samples):",
            status,
            category_report.category.name(),
            stats.count
        );
        info!(
            "    P50: {:.1}μs | P95: {:.1}μs | P99: {:.1}μs | P99.9: {:.1}μs",
            stats.p50_us(),
            stats.p95_us(),
            stats.p99_us(),
            stats.p99_9_ns as f64 / 1_000.0
        );
        info!(
            "    Min: {:.1}μs | Max: {:.1}μs | Mean: {:.1}μs | StdDev: {:.1}μs",
            stats.min_ns as f64 / 1_000.0,
            stats.max_ns as f64 / 1_000.0,
            stats.mean_ns as f64 / 1_000.0,
            stats.stddev_ns as f64 / 1_000.0
        );
    }

    // Recommendations
    info!("Recommendations:");
    if results.target_met {
        info!("  🚀 System is ready for production deployment");
        info!("  🔧 Consider running comprehensive test for final validation");
        info!("  📈 Monitor latency in production with continuous measurement");
    } else {
        info!("  🔧 Optimization needed for categories that did not meet targets");
        info!("  📊 Focus on P95+ percentiles for consistent performance");
        info!("  🎯 Consider adjusting concurrency or load patterns");
        info!("  🔍 Profile specific operations causing high latency");
    }

    info!("================================");
}
