#![allow(
    clippy::unwrap_used,
    clippy::expect_used,
    clippy::indexing_slicing,
    clippy::str_to_string,
    clippy::useless_vec,
    clippy::shadow_unrelated,
    clippy::similar_names,
    unused_imports,
    unused_variables,
    dead_code,
)]
//! Trading Engine Latency Benchmarks
//!
//! Validates critical trading path performance targets:
//! - Order processing pipeline: <50μs p99
//! - Risk validation: <5μs p99
//! - Market data processing: <10μs p99
//! - Event queue operations: <1μs p99
//!
//! These benchmarks establish regression baselines for CI/CD integration.

use criterion::{black_box, criterion_group, criterion_main, Criterion, Throughput};
use std::time::Duration;

// Core trading types
use chrono::Utc;
use common::{
    HftTimestamp, Order, OrderId, OrderSide, OrderType, Position, Price, Quantity, Symbol,
    TimeInForce,
};
use rust_decimal::prelude::FromPrimitive;
use rust_decimal::Decimal;
use serde_json::json;
use trading_engine::types::events::MarketEvent;
use uuid::Uuid;

/// Benchmark order creation and validation
fn bench_order_creation(c: &mut Criterion) {
    let mut group = c.benchmark_group("order_creation");

    let symbol = Symbol::new("BTCUSD".to_string());
    let price = Price::from_f64(50000.0).unwrap();
    let quantity = Quantity::from_f64(1.0).unwrap();

    group.bench_function("create_limit_order", |b| {
        b.iter(|| {
            let order = Order {
                // Core Identity
                id: OrderId::new(),
                client_order_id: None,
                broker_order_id: None,
                account_id: None,

                // Trading Details
                symbol: symbol.clone(),
                side: OrderSide::Buy,
                order_type: OrderType::Limit,
                status: common::OrderStatus::New,
                time_in_force: TimeInForce::default(),

                // Quantities & Pricing
                quantity,
                price: Some(price),
                stop_price: None,
                filled_quantity: Quantity::ZERO,
                remaining_quantity: quantity,
                average_price: None,
                avg_fill_price: None,
                average_fill_price: None,
                exchange_order_id: None,

                // Strategy Fields
                parent_id: None,
                execution_algorithm: None,
                execution_params: json!({}),

                // Risk Management
                stop_loss: None,
                take_profit: None,

                // Timestamps
                created_at: HftTimestamp::now_or_zero(),
                updated_at: None,
                expires_at: None,

                // Extensibility
                metadata: json!({}),
            };
            black_box(order)
        });
    });

    group.bench_function("create_market_order", |b| {
        b.iter(|| {
            let order = Order {
                // Core Identity
                id: OrderId::new(),
                client_order_id: None,
                broker_order_id: None,
                account_id: None,

                // Trading Details
                symbol: symbol.clone(),
                side: OrderSide::Sell,
                order_type: OrderType::Market,
                status: common::OrderStatus::New,
                time_in_force: TimeInForce::default(),

                // Quantities & Pricing
                quantity,
                price: None,
                stop_price: None,
                filled_quantity: Quantity::ZERO,
                remaining_quantity: quantity,
                average_price: None,
                avg_fill_price: None,
                average_fill_price: None,
                exchange_order_id: None,

                // Strategy Fields
                parent_id: None,
                execution_algorithm: None,
                execution_params: json!({}),

                // Risk Management
                stop_loss: None,
                take_profit: None,

                // Timestamps
                created_at: HftTimestamp::now_or_zero(),
                updated_at: None,
                expires_at: None,

                // Extensibility
                metadata: json!({}),
            };
            black_box(order)
        });
    });

    group.finish();
}

/// Benchmark market event processing
fn bench_market_event_processing(c: &mut Criterion) {
    let mut group = c.benchmark_group("market_event_processing");
    group.throughput(Throughput::Elements(1));

    let symbol = Symbol::new("BTCUSD".to_string());
    let price = Price::from_f64(50000.0).unwrap();
    let size = Quantity::from_f64(1.0).unwrap();

    group.bench_function("trade_event_creation", |b| {
        b.iter(|| {
            let event = MarketEvent::Trade {
                symbol: symbol.clone(),
                price,
                size,
                timestamp: Utc::now(),
                side: Some(OrderSide::Buy),
                venue: None,
                trade_id: None,
            };
            black_box(event)
        });
    });

    group.bench_function("quote_event_creation", |b| {
        b.iter(|| {
            let event = MarketEvent::Quote {
                symbol: symbol.clone(),
                bid_price: price,
                ask_price: Price::from_f64(50010.0).unwrap(),
                bid_size: size,
                ask_size: size,
                timestamp: Utc::now(),
                venue: None,
            };
            black_box(event)
        });
    });

    group.finish();
}

/// Benchmark position calculations
fn bench_position_calculations(c: &mut Criterion) {
    let mut group = c.benchmark_group("position_calculations");

    let now = Utc::now();
    let mut position = Position {
        id: Uuid::new_v4(),
        symbol: "BTCUSD".to_string(),
        quantity: Decimal::from(10),
        avg_price: Decimal::from(50000),
        avg_cost: Decimal::from(50000),
        basis: Decimal::from(500000),
        average_price: Decimal::from(50000),
        market_value: Decimal::from(500000),
        unrealized_pnl: Decimal::ZERO,
        realized_pnl: Decimal::ZERO,
        created_at: now,
        updated_at: now,
        last_updated: now,
        current_price: Some(Decimal::from(50000)),
        notional_value: Decimal::from(500000),
        margin_requirement: Decimal::from(50000),
    };

    group.bench_function("update_market_value", |b| {
        b.iter(|| {
            let new_price = Decimal::from(50100);
            position.market_value = position.quantity * new_price;
            position.unrealized_pnl =
                position.market_value - (position.quantity * position.average_price);
            black_box(())
        });
    });

    group.bench_function("calculate_pnl", |b| {
        b.iter(|| {
            let current_price = Decimal::from(50100);
            let pnl = (current_price - position.average_price) * position.quantity;
            black_box(pnl)
        });
    });

    group.finish();
}

/// Benchmark order book update latency
fn bench_order_book_updates(c: &mut Criterion) {
    let mut group = c.benchmark_group("order_book_updates");
    group.throughput(Throughput::Elements(1));

    // Simulate order book level updates
    let mut bids: Vec<(Price, Quantity)> = Vec::with_capacity(100);
    let mut asks: Vec<(Price, Quantity)> = Vec::with_capacity(100);

    for i in 0..100 {
        bids.push((
            Price::from_f64(50000.0 - i as f64).unwrap(),
            Quantity::from_f64(10.0).unwrap(),
        ));
        asks.push((
            Price::from_f64(50000.0 + i as f64).unwrap(),
            Quantity::from_f64(10.0).unwrap(),
        ));
    }

    let new_bid = (
        Price::from_f64(49950.0).unwrap(),
        Quantity::from_f64(5.0).unwrap(),
    );

    group.bench_function("insert_bid", |b| {
        b.iter(|| {
            bids.insert(0, new_bid);
            bids.truncate(100);
            black_box(())
        });
    });

    group.bench_function("best_bid_ask", |b| {
        b.iter(|| {
            let best_bid = bids.first();
            let best_ask = asks.first();
            black_box((best_bid, best_ask))
        });
    });

    group.finish();
}

/// Benchmark event queue operations (critical for <1μs target)
fn bench_event_queue(c: &mut Criterion) {
    let mut group = c.benchmark_group("event_queue");
    group.throughput(Throughput::Elements(1));

    use std::collections::VecDeque;
    let mut queue: VecDeque<MarketEvent> = VecDeque::with_capacity(1000);

    let symbol = Symbol::new("BTCUSD".to_string());
    let event = MarketEvent::Trade {
        symbol: symbol.clone(),
        price: Price::from_f64(50000.0).unwrap(),
        size: Quantity::from_f64(1.0).unwrap(),
        timestamp: Utc::now(),
        side: Some(OrderSide::Buy),
        venue: None,
        trade_id: None,
    };

    group.bench_function("push_event", |b| {
        b.iter(|| {
            queue.push_back(event.clone());
            black_box(())
        });
    });

    group.bench_function("pop_event", |b| {
        b.iter(|| {
            if queue.is_empty() {
                queue.push_back(event.clone());
            }
            let popped = queue.pop_front();
            black_box(popped)
        });
    });

    group.bench_function("push_pop_cycle", |b| {
        b.iter(|| {
            queue.push_back(event.clone());
            let popped = queue.pop_front();
            black_box(popped)
        });
    });

    group.finish();
}

/// End-to-end order processing pipeline benchmark
fn bench_order_pipeline(c: &mut Criterion) {
    let mut group = c.benchmark_group("order_pipeline");
    group.measurement_time(Duration::from_secs(15));

    let symbol = Symbol::new("BTCUSD".to_string());
    let price = Price::from_f64(50000.0).unwrap();
    let quantity = Quantity::from_f64(1.0).unwrap();

    group.bench_function("end_to_end_order_processing", |b| {
        b.iter(|| {
            // 1. Create order
            let order = Order {
                // Core Identity
                id: OrderId::new(),
                client_order_id: None,
                broker_order_id: None,
                account_id: None,

                // Trading Details
                symbol: symbol.clone(),
                side: OrderSide::Buy,
                order_type: OrderType::Limit,
                status: common::OrderStatus::New,
                time_in_force: TimeInForce::default(),

                // Quantities & Pricing
                quantity,
                price: Some(price),
                stop_price: None,
                filled_quantity: Quantity::ZERO,
                remaining_quantity: quantity,
                average_price: None,
                avg_fill_price: None,
                average_fill_price: None,
                exchange_order_id: None,

                // Strategy Fields
                parent_id: None,
                execution_algorithm: None,
                execution_params: json!({}),

                // Risk Management
                stop_loss: None,
                take_profit: None,

                // Timestamps
                created_at: HftTimestamp::now_or_zero(),
                updated_at: None,
                expires_at: None,

                // Extensibility
                metadata: json!({}),
            };

            // 2. Validate (simulated)
            let is_valid = order.quantity > Quantity::ZERO && order.price.is_some();

            // 3. Calculate risk (simulated)
            let position_size = Decimal::from_f64_retain(order.quantity.as_f64()).unwrap();
            let max_position = Decimal::from(100);
            let risk_ok = position_size <= max_position;

            black_box((order, is_valid, risk_ok))
        });
    });

    group.finish();
}

criterion_group! {
    name = trading_latency_benchmarks;
    config = Criterion::default()
        .measurement_time(Duration::from_secs(10))
        .sample_size(1000)
        .warm_up_time(Duration::from_secs(3))
        .with_plots();
    targets =
        bench_order_creation,
        bench_market_event_processing,
        bench_position_calculations,
        bench_order_book_updates,
        bench_event_queue,
        bench_order_pipeline
}

criterion_main!(trading_latency_benchmarks);

#[cfg(test)]
mod latency_validation {

    #[test]
    fn validate_order_creation_latency() {
        let symbol = Symbol::new("BTCUSD".to_string());
        let price = Price::from_f64(50000.0).unwrap();
        let quantity = Quantity::from_f64(1.0).unwrap();

        let iterations = 10000;
        let start = Instant::now();

        for _ in 0..iterations {
            let _order = Order {
                // Core Identity
                id: OrderId::new(),
                client_order_id: None,
                broker_order_id: None,
                account_id: None,

                // Trading Details
                symbol: symbol.clone(),
                side: OrderSide::Buy,
                order_type: OrderType::Limit,
                status: common::OrderStatus::New,
                time_in_force: TimeInForce::default(),

                // Quantities & Pricing
                quantity,
                price: Some(price),
                stop_price: None,
                filled_quantity: Quantity::ZERO,
                remaining_quantity: quantity,
                average_price: None,
                avg_fill_price: None,
                average_fill_price: None,
                exchange_order_id: None,

                // Strategy Fields                parent_id: None,
                execution_algorithm: None,
                execution_params: json!({}),

                // Risk Management
                stop_loss: None,
                take_profit: None,

                // Timestamps
                created_at: HftTimestamp::now_or_zero(),
                updated_at: None,
                expires_at: None,

                // Extensibility
                metadata: json!({}),
            };
        }

        let elapsed = start.elapsed();
        let avg_latency_us = elapsed.as_micros() / iterations;

        println!("✓ Average order creation: {}μs", avg_latency_us);
        assert!(
            avg_latency_us < 50,
            "Order creation exceeds 50μs target: {}μs",
            avg_latency_us
        );
    }

    #[test]
    fn validate_event_queue_latency() {
        use std::collections::VecDeque;
        let mut queue: VecDeque<MarketEvent> = VecDeque::with_capacity(1000);

        let symbol = Symbol::new("BTCUSD".to_string());
        let event = MarketEvent::Trade {
            symbol: symbol.clone(),
            price: Price::from_f64(50000.0).unwrap(),
            size: Quantity::from_f64(1.0).unwrap(),
            timestamp: Utc::now(),
            side: Some(OrderSide::Buy),
            venue: None,
            trade_id: None,
        };

        let iterations = 100000;
        let start = Instant::now();

        for _ in 0..iterations {
            queue.push_back(event.clone());
            let _ = queue.pop_front();
        }

        let elapsed = start.elapsed();
        let avg_latency_ns = elapsed.as_nanos() / iterations;

        println!("✓ Average queue push/pop: {}ns", avg_latency_ns);
        assert!(
            avg_latency_ns < 1000,
            "Queue operations exceed 1μs target: {}ns",
            avg_latency_ns
        );
    }
}
