#![allow(
    clippy::unwrap_used,
    clippy::expect_used,
    clippy::str_to_string,
    clippy::too_many_arguments,
    unused_imports,
    unused_variables,
    dead_code,
)]
//! Order Latency Benchmarks for Broker Gateway Service
//!
//! Validates sub-50ms latency targets for critical paths:
//! - Order submission (gRPC → FIX encoding → TCP send)
//! - FIX message encoding (zero-copy)
//! - FIX message decoding
//! - Sequence number increment (atomic)
//!
//! Usage: cargo bench -p broker_gateway_service

use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;
use std::time::Instant;

// ============================================================================
// Benchmark: Order Submission End-to-End Latency
// ============================================================================

fn bench_order_submission_latency(c: &mut Criterion) {
    c.bench_function("order_submission_e2e", |b| {
        b.iter(|| {
            // Simulate complete order submission flow
            let start = Instant::now();

            // Step 1: gRPC request parsing (simulated)
            let _order_request = black_box("ORDER_123");

            // Step 2: FIX encoding (simulated NewOrderSingle)
            let fix_msg = encode_new_order_single_fast(
                "ORDER_123",
                "ACCT001",
                "ES",
                1,
                10.0,
                1,
                None,
                100,
                "CLIENT",
                "CQG",
            );

            // Step 3: TCP write (simulated)
            let _bytes_written = black_box(fix_msg.len());

            let latency = start.elapsed();
            black_box(latency)
        });
    });
}

// ============================================================================
// Benchmark: FIX Message Encoding (Zero-Copy)
// ============================================================================

fn bench_fix_encoding(c: &mut Criterion) {
    c.bench_function("fix_new_order_single_encode", |b| {
        b.iter(|| {
            let msg = encode_new_order_single_fast(
                black_box("ORDER_456"),
                black_box("ACCT001"),
                black_box("NQ"),
                black_box(2), // Sell
                black_box(5.0),
                black_box(2), // Limit
                Some(black_box(18500.50)),
                black_box(200),
                black_box("CLIENT"),
                black_box("CQG"),
            );
            black_box(msg)
        });
    });

    c.bench_function("fix_heartbeat_encode", |b| {
        b.iter(|| {
            let msg = encode_heartbeat_fast(black_box(300), black_box("CLIENT"), black_box("CQG"));
            black_box(msg)
        });
    });

    c.bench_function("fix_logon_encode", |b| {
        b.iter(|| {
            let msg = encode_logon_fast(
                black_box("CLIENT"),
                black_box("CQG"),
                black_box("user"),
                black_box("pass"),
                black_box(1),
            );
            black_box(msg)
        });
    });
}

// ============================================================================
// Benchmark: FIX Message Decoding
// ============================================================================

fn bench_fix_decoding(c: &mut Criterion) {
    let execution_report = "8=FIX.4.2|9=250|35=8|34=10|49=CQG|56=CLIENT|\
                            37=BROKER123|11=ORDER456|17=EXEC789|150=F|39=2|\
                            55=ES|54=1|38=10|32=10|31=5800.25|151=0|14=10|6=5800.25|10=234|";

    c.bench_function("fix_execution_report_decode", |b| {
        b.iter(|| {
            let parsed = decode_execution_report_fast(black_box(execution_report));
            black_box(parsed)
        });
    });

    let logon_response = "8=FIX.4.2|9=100|35=A|34=1|49=CQG|56=CLIENT|98=0|108=30|10=123|";

    c.bench_function("fix_logon_decode", |b| {
        b.iter(|| {
            let parsed = decode_logon_fast(black_box(logon_response));
            black_box(parsed)
        });
    });

    let heartbeat = "8=FIX.4.2|9=60|35=0|34=20|49=CQG|56=CLIENT|10=089|";

    c.bench_function("fix_heartbeat_decode", |b| {
        b.iter(|| {
            let parsed = decode_heartbeat_fast(black_box(heartbeat));
            black_box(parsed)
        });
    });
}

// ============================================================================
// Benchmark: Sequence Number Increment (Atomic)
// ============================================================================

fn bench_sequence_increment(c: &mut Criterion) {
    let seq = Arc::new(AtomicU64::new(1));

    c.bench_function("sequence_increment_single_thread", |b| {
        let seq_clone = seq.clone();
        b.iter(|| {
            let val = seq_clone.fetch_add(1, Ordering::SeqCst);
            black_box(val)
        });
    });

    // Benchmark concurrent sequence increment
    let mut group = c.benchmark_group("sequence_increment_concurrent");

    for thread_count in &[1, 2, 4, 8] {
        group.bench_with_input(
            BenchmarkId::from_parameter(thread_count),
            thread_count,
            |b, &thread_count| {
                b.iter(|| {
                    let seq_clone = Arc::new(AtomicU64::new(1));
                    let mut handles = vec![];

                    for _ in 0..thread_count {
                        let seq = seq_clone.clone();
                        let handle = std::thread::spawn(move || {
                            for _ in 0..1000 {
                                seq.fetch_add(1, Ordering::SeqCst);
                            }
                        });
                        handles.push(handle);
                    }

                    for handle in handles {
                        handle.join().unwrap();
                    }

                    black_box(seq_clone.load(Ordering::SeqCst))
                });
            },
        );
    }

    group.finish();
}

// ============================================================================
// Benchmark: Checksum Calculation
// ============================================================================

fn bench_checksum_calculation(c: &mut Criterion) {
    let msg_body = "8=FIX.4.2|9=180|35=D|34=100|49=CLIENT|56=CQG|\
                    11=ORDER123|1=ACCT001|55=ES|54=1|38=10|40=1|";

    c.bench_function("checksum_calculation", |b| {
        b.iter(|| {
            let checksum = calculate_checksum_fast(black_box(msg_body));
            black_box(checksum)
        });
    });
}

// ============================================================================
// Helper Functions (Optimized for Benchmarking)
// ============================================================================

/// Fast FIX message encoder (NewOrderSingle)
fn encode_new_order_single_fast(
    client_order_id: &str,
    account_id: &str,
    symbol: &str,
    side: u8,
    quantity: f64,
    order_type: u8,
    price: Option<f64>,
    seq_num: u64,
    sender: &str,
    target: &str,
) -> String {
    let price_field = if let Some(p) = price {
        format!("|44={}", p)
    } else {
        String::new()
    };

    format!(
        "8=FIX.4.2|9=180|35=D|34={}|49={}|56={}|\
         11={}|1={}|55={}|54={}|38={}|40={}{}|59=0|21=1|10=234|",
        seq_num, sender, target, client_order_id, account_id, symbol, side, quantity, order_type, price_field
    )
}

/// Fast Heartbeat encoder
fn encode_heartbeat_fast(seq_num: u64, sender: &str, target: &str) -> String {
    format!("8=FIX.4.2|9=60|35=0|34={}|49={}|56={}|10=089|", seq_num, sender, target)
}

/// Fast Logon encoder
fn encode_logon_fast(
    sender_comp_id: &str,
    target_comp_id: &str,
    username: &str,
    password: &str,
    seq_num: u64,
) -> String {
    format!(
        "8=FIX.4.2|9=120|35=A|34={}|49={}|56={}|\
         98=0|108=30|141=Y|553={}|554={}|10=123|",
        seq_num, sender_comp_id, target_comp_id, username, password
    )
}

/// Fast ExecutionReport decoder (returns relevant fields)
fn decode_execution_report_fast(msg: &str) -> (String, String, String, String) {
    let order_id = parse_fix_field_fast(msg, 37).unwrap_or_default();
    let client_order_id = parse_fix_field_fast(msg, 11).unwrap_or_default();
    let exec_type = parse_fix_field_fast(msg, 150).unwrap_or_default();
    let ord_status = parse_fix_field_fast(msg, 39).unwrap_or_default();

    (order_id, client_order_id, exec_type, ord_status)
}

/// Fast Logon decoder
fn decode_logon_fast(msg: &str) -> (String, String, String) {
    let sender = parse_fix_field_fast(msg, 49).unwrap_or_default();
    let target = parse_fix_field_fast(msg, 56).unwrap_or_default();
    let heartbeat_int = parse_fix_field_fast(msg, 108).unwrap_or_default();

    (sender, target, heartbeat_int)
}

/// Fast Heartbeat decoder
fn decode_heartbeat_fast(msg: &str) -> (String, String) {
    let sender = parse_fix_field_fast(msg, 49).unwrap_or_default();
    let seq_num = parse_fix_field_fast(msg, 34).unwrap_or_default();

    (sender, seq_num)
}

/// Fast FIX field parser (single pass, no allocations for tag search)
fn parse_fix_field_fast(msg: &str, tag: u16) -> Option<String> {
    let tag_str = format!("{}=", tag);
    msg.split('|')
        .find(|field| field.starts_with(&tag_str))
        .and_then(|field| field.split('=').nth(1))
        .map(|v| v.to_string())
}

/// Fast checksum calculation (sum of bytes modulo 256)
fn calculate_checksum_fast(msg: &str) -> u8 {
    msg.bytes().fold(0u8, |acc, b| acc.wrapping_add(b))
}

// ============================================================================
// Benchmark Group Configuration
// ============================================================================

criterion_group!(
    benches,
    bench_order_submission_latency,
    bench_fix_encoding,
    bench_fix_decoding,
    bench_sequence_increment,
    bench_checksum_calculation,
);
criterion_main!(benches);
