//! Comprehensive tests for common/types module
//!
//! This test suite provides extensive coverage for all types in common/src/types.rs:
//! - Numeric types (Price, Quantity) with fixed-point arithmetic
//! - Identifier wrapper types with validation
//! - Enum types with TryFrom and Display
//! - Complex structs with business logic (Order, Position, Execution)
//! - Market data event types
//! - Error handling and serialization
//!
//! Coverage: 70+ test cases, 1,500+ lines targeting all 60+ public types

use chrono::{Datelike, Utc};
use common::types::*;
use rust_decimal::Decimal;
use std::str::FromStr;
use std::thread;

// =============================================================================
// MODULE A: NUMERIC TYPES - Price and Quantity (28 tests)
// =============================================================================

#[test]
fn test_price_construction_from_f64() {
    // Valid prices
    assert!(Price::from_f64(0.0).is_ok());
    assert!(Price::from_f64(100.0).is_ok());
    assert!(Price::from_f64(99.99999999).is_ok());

    // Invalid prices
    assert!(Price::from_f64(-1.0).is_err());
    assert!(Price::from_f64(f64::NAN).is_err());
    assert!(Price::from_f64(f64::INFINITY).is_err());
    assert!(Price::from_f64(f64::NEG_INFINITY).is_err());
}

#[test]
fn test_price_constants() {
    assert_eq!(Price::ZERO.to_f64(), 0.0);
    assert_eq!(Price::ONE.to_f64(), 1.0);
    assert_eq!(Price::CENT.to_f64(), 0.01);
    assert!(Price::MAX.to_f64() > 1_000_000_000.0);
}

#[test]
fn test_price_arithmetic_addition() {
    let p1 = Price::from_f64(10.5).unwrap();
    let p2 = Price::from_f64(5.25).unwrap();
    let sum = p1 + p2;

    assert!((sum.to_f64() - 15.75).abs() < 1e-6);
}

#[test]
fn test_price_arithmetic_subtraction() {
    let p1 = Price::from_f64(10.5).unwrap();
    let p2 = Price::from_f64(5.25).unwrap();
    let diff = p1 - p2;

    assert!((diff.to_f64() - 5.25).abs() < 1e-6);
}

#[test]
fn test_price_arithmetic_multiplication() {
    let p = Price::from_f64(10.0).unwrap();
    let result = (p * 2.5).unwrap();

    assert!((result.to_f64() - 25.0).abs() < 1e-6);
}

#[test]
fn test_price_arithmetic_division() {
    let p = Price::from_f64(100.0).unwrap();
    let result = (p / 4.0).unwrap();

    assert!((result.to_f64() - 25.0).abs() < 1e-6);
}

#[test]
fn test_price_division_by_zero() {
    let p = Price::from_f64(100.0).unwrap();
    let result = p / 0.0;

    assert!(result.is_err());
}

#[test]
fn test_price_saturation_addition() {
    let p1 = Price::MAX;
    let p2 = Price::ONE;
    let sum = p1 + p2;

    // Should saturate at MAX, not overflow
    assert_eq!(sum, Price::MAX);
}

#[test]
fn test_price_saturation_subtraction() {
    let p1 = Price::ZERO;
    let p2 = Price::ONE;
    let diff = p1 - p2;

    // Should saturate at ZERO, not underflow
    assert_eq!(diff, Price::ZERO);
}

#[test]
fn test_price_comparison_with_f64() {
    let p = Price::from_f64(10.5).unwrap();

    assert!(p == 10.5);
    assert!(p != 10.6);
    assert!(p < 11.0);
    assert!(p > 10.0);
}

#[test]
fn test_price_display_formatting() {
    let p = Price::from_f64(123.456789).unwrap();
    let display = format!("{}", p);

    // Should display with 8 decimal places
    assert!(display.contains("123.45678"));
}

#[test]
fn test_price_from_str() {
    let p = Price::from_str("99.99").unwrap();
    assert!((p.to_f64() - 99.99).abs() < 1e-6);

    // Invalid string
    assert!(Price::from_str("invalid").is_err());
    assert!(Price::from_str("-10").is_err());
}

#[test]
fn test_price_to_from_decimal() {
    let price = Price::from_f64(123.45).unwrap();
    let decimal = price.to_decimal().unwrap();
    let back_to_price = Price::from_decimal(decimal);

    assert!((back_to_price.to_f64() - 123.45).abs() < 1e-6);
}

#[test]
fn test_price_cents_conversion() {
    let p = Price::from_cents(150); // 1.50 in cents
    assert!((p.to_f64() - 1.50).abs() < 1e-6);
    assert_eq!(p.to_cents(), 150);
}

#[test]
fn test_quantity_construction_from_f64() {
    // Valid quantities
    assert!(Quantity::from_f64(0.0).is_ok());
    assert!(Quantity::from_f64(100.5).is_ok());

    // Invalid quantities
    assert!(Quantity::from_f64(-1.0).is_err());
    assert!(Quantity::from_f64(f64::NAN).is_err());
}

#[test]
fn test_quantity_constants() {
    assert_eq!(Quantity::ZERO.to_f64(), 0.0);
    assert_eq!(Quantity::ONE.to_f64(), 1.0);
    assert!(Quantity::MAX.to_f64() > 1_000_000_000.0);
}

#[test]
fn test_quantity_arithmetic() {
    let q1 = Quantity::from_f64(10.5).unwrap();
    let q2 = Quantity::from_f64(5.25).unwrap();

    let sum = q1 + q2;
    assert!((sum.to_f64() - 15.75).abs() < 1e-6);

    let diff = q1 - q2;
    assert!((diff.to_f64() - 5.25).abs() < 1e-6);
}

#[test]
fn test_quantity_sum_trait() {
    let quantities = [
        Quantity::from_f64(1.0).unwrap(),
        Quantity::from_f64(2.0).unwrap(),
        Quantity::from_f64(3.0).unwrap(),
    ];

    let total: Quantity = quantities.iter().copied().sum();
    assert!((total.to_f64() - 6.0).abs() < 1e-6);
}

#[test]
fn test_quantity_shares_conversion() {
    let q = Quantity::from_shares(100);
    assert_eq!(q.to_f64(), 100.0);
    assert_eq!(q.to_shares(), 100);
}

#[test]
fn test_quantity_is_zero() {
    assert!(Quantity::ZERO.is_zero());
    assert!(!Quantity::ONE.is_zero());

    let q = Quantity::from_f64(0.0).unwrap();
    assert!(q.is_zero());
}

#[test]
fn test_quantity_is_positive() {
    assert!(!Quantity::ZERO.is_positive());
    assert!(Quantity::ONE.is_positive());

    let q = Quantity::from_f64(10.5).unwrap();
    assert!(q.is_positive());
}

#[test]
fn test_quantity_try_from_decimal() {
    let decimal = Decimal::from_str("123.45").unwrap();
    let qty = Quantity::try_from(decimal).unwrap();

    assert!((qty.to_f64() - 123.45).abs() < 1e-6);
}

#[test]
fn test_price_quantity_multiply() {
    let price = Price::from_f64(10.5).unwrap();
    let qty = Quantity::from_f64(5.0).unwrap();

    // Notional value calculation
    let value = price.to_f64() * qty.to_f64();
    assert!((value - 52.5).abs() < 1e-6);
}

#[test]
fn test_price_add_assign() {
    let mut p = Price::from_f64(10.0).unwrap();
    p += Price::from_f64(5.0).unwrap();

    assert!((p.to_f64() - 15.0).abs() < 1e-6);
}

#[test]
fn test_quantity_sub_assign() {
    let mut q = Quantity::from_f64(10.0).unwrap();
    // Quantity doesn't implement SubAssign, use explicit subtraction
    q = q - Quantity::from_f64(3.0).unwrap();

    assert!((q.to_f64() - 7.0).abs() < 1e-6);
}

#[test]
fn test_volume_type_alias() {
    let vol: Volume = Quantity::from_f64(1000.0).unwrap();
    assert_eq!(vol.to_f64(), 1000.0);
}

#[test]
fn test_price_equality_with_epsilon() {
    let p1 = Price::from_f64(10.5).unwrap();
    let p2 = Price::from_f64(10.5).unwrap();

    assert_eq!(p1, p2);
    assert!(p1 == 10.5);
}

// =============================================================================
// MODULE B: IDENTIFIER TYPES (14 tests)
// =============================================================================

#[test]
fn test_service_id_creation() {
    let id = ServiceId::new("trading-service-1");
    assert_eq!(id.as_str(), "trading-service-1");
}

#[test]
fn test_service_id_from_string() {
    let id = ServiceId::from("test-service".to_owned());
    assert_eq!(id.as_str(), "test-service");
}

#[test]
fn test_service_id_display() {
    let id = ServiceId::new("service-123");
    assert_eq!(format!("{}", id), "service-123");
}

#[test]
fn test_order_id_atomic_generation() {
    let id1 = OrderId::new();
    let id2 = OrderId::new();
    let id3 = OrderId::new();

    // IDs should be sequential and unique
    assert_ne!(id1, id2);
    assert_ne!(id2, id3);
    assert!(id2.value() > id1.value());
    assert!(id3.value() > id2.value());
}

#[test]
fn test_order_id_concurrent_generation() {
    let handles: Vec<_> = (0..10)
        .map(|_| {
            thread::spawn(|| {
                let mut ids = Vec::new();
                for _ in 0..100 {
                    ids.push(OrderId::new());
                }
                ids
            })
        })
        .collect();

    let mut all_ids = Vec::new();
    for handle in handles {
        all_ids.extend(handle.join().unwrap());
    }

    // Check all IDs are unique
    let unique_count = all_ids
        .iter()
        .collect::<std::collections::HashSet<_>>()
        .len();
    assert_eq!(unique_count, 1000);
}

#[test]
fn test_order_id_from_u64() {
    let id = OrderId::from_u64(12345);
    assert_eq!(id.value(), 12345);
    assert_eq!(id.as_u64(), 12345);
}

#[test]
fn test_order_id_from_string() {
    let id = OrderId::from("12345".to_owned());
    assert_eq!(id.value(), 12345);

    // Invalid string should generate new ID
    let id_invalid = OrderId::from("not-a-number".to_owned());
    assert!(id_invalid.value() > 0);
}

#[test]
fn test_order_id_display() {
    let id = OrderId::from_u64(99999);
    assert_eq!(format!("{}", id), "99999");
}

#[test]
fn test_execution_id_validation() {
    // Valid
    let id = ExecutionId::new("exec-123").unwrap();
    assert_eq!(id.as_str(), "exec-123");

    // Empty should fail
    assert!(ExecutionId::new("").is_err());
    assert!(ExecutionId::new("   ").is_err());
}

#[test]
fn test_execution_id_generate() {
    let id = ExecutionId::generate();
    assert!(!id.as_str().is_empty());

    // Should be UUID format
    assert!(id.as_str().contains("-"));
}

#[test]
fn test_trade_id_validation() {
    let id = TradeId::new("trade-456").unwrap();
    assert_eq!(id.as_str(), "trade-456");

    assert!(TradeId::new("").is_err());
}

#[test]
fn test_symbol_creation() {
    let sym = Symbol::from("AAPL");
    assert_eq!(sym.as_str(), "AAPL");
    assert!(!sym.is_empty());
}

#[test]
fn test_symbol_validation() {
    // No validation version
    let sym = Symbol::from("");
    assert!(sym.is_empty());

    // Validated version
    assert!(Symbol::new_validated("AAPL".to_owned()).is_ok());
    assert!(Symbol::new_validated("".to_owned()).is_err());
    assert!(Symbol::new_validated("   ".to_owned()).is_err());
}

#[test]
fn test_symbol_operations() {
    let sym = Symbol::from("aapl");

    assert_eq!(sym.to_uppercase(), "AAPL");
    assert!(sym.contains("aa"));
    assert!(!sym.contains("ZZ"));

    let replaced = sym.replace("aa", "AA");
    assert_eq!(replaced, "AApl");
}

// =============================================================================
// MODULE C: ENUM TYPES (18 tests)
// =============================================================================

#[test]
fn test_order_type_variants() {
    assert_eq!(OrderType::Market.to_string(), "MARKET");
    assert_eq!(OrderType::Limit.to_string(), "LIMIT");
    assert_eq!(OrderType::Stop.to_string(), "STOP");
    assert_eq!(OrderType::StopLimit.to_string(), "STOP_LIMIT");
    assert_eq!(OrderType::Iceberg.to_string(), "ICEBERG");
    assert_eq!(OrderType::TrailingStop.to_string(), "TRAILING_STOP");
    assert_eq!(OrderType::Hidden.to_string(), "HIDDEN");
}

#[test]
fn test_order_type_default() {
    assert_eq!(OrderType::default(), OrderType::Market);
}

#[test]
fn test_order_type_try_from_i32() {
    assert_eq!(OrderType::try_from(0).unwrap().to_string(), "MARKET");
    assert_eq!(OrderType::try_from(1).unwrap().to_string(), "LIMIT");
    assert_eq!(OrderType::try_from(2).unwrap().to_string(), "STOP");
    assert_eq!(OrderType::try_from(3).unwrap().to_string(), "STOP_LIMIT");

    // Invalid value
    assert!(OrderType::try_from(999).is_err());
}

#[test]
fn test_order_status_variants() {
    assert_eq!(OrderStatus::Created.to_string(), "CREATED");
    assert_eq!(OrderStatus::Submitted.to_string(), "SUBMITTED");
    assert_eq!(OrderStatus::PartiallyFilled.to_string(), "PARTIALLY_FILLED");
    assert_eq!(OrderStatus::Filled.to_string(), "FILLED");
    assert_eq!(OrderStatus::Rejected.to_string(), "REJECTED");
    assert_eq!(OrderStatus::Cancelled.to_string(), "CANCELLED");
}

#[test]
fn test_order_status_try_from_i32() {
    assert_eq!(OrderStatus::try_from(0).unwrap(), OrderStatus::Created);
    assert_eq!(OrderStatus::try_from(3).unwrap(), OrderStatus::Filled);
    assert_eq!(OrderStatus::try_from(5).unwrap(), OrderStatus::Cancelled);

    assert!(OrderStatus::try_from(999).is_err());
}

#[test]
fn test_order_side_variants() {
    assert_eq!(OrderSide::Buy.to_string(), "BUY");
    assert_eq!(OrderSide::Sell.to_string(), "SELL");
}

#[test]
fn test_order_side_try_from_i32() {
    assert_eq!(OrderSide::try_from(0).unwrap(), OrderSide::Buy);
    assert_eq!(OrderSide::try_from(1).unwrap(), OrderSide::Sell);

    assert!(OrderSide::try_from(2).is_err());
}

#[test]
fn test_currency_variants() {
    assert_eq!(Currency::USD.to_string(), "USD");
    assert_eq!(Currency::EUR.to_string(), "EUR");
    assert_eq!(Currency::GBP.to_string(), "GBP");
    assert_eq!(Currency::JPY.to_string(), "JPY");
    assert_eq!(Currency::BTC.to_string(), "BTC");
    assert_eq!(Currency::ETH.to_string(), "ETH");
}

#[test]
fn test_currency_default() {
    assert_eq!(Currency::default(), Currency::USD);
}

#[test]
fn test_currency_ordering() {
    // Currency implements Ord
    assert!(Currency::AUD < Currency::BTC);
    assert!(Currency::USD < Currency::EUR); // Declaration order: USD is index 0, EUR is index 1
}

#[test]
fn test_time_in_force_variants() {
    assert_eq!(TimeInForce::Day.to_string(), "DAY");
    assert_eq!(TimeInForce::GoodTillCancel.to_string(), "GTC");
    assert_eq!(TimeInForce::ImmediateOrCancel.to_string(), "IOC");
    assert_eq!(TimeInForce::FillOrKill.to_string(), "FOK");
}

#[test]
fn test_broker_type_default() {
    assert_eq!(BrokerType::default(), BrokerType::InteractiveBrokers);
}

#[test]
fn test_service_status_healthy() {
    assert!(ServiceStatus::Running.is_healthy());
    assert!(ServiceStatus::Starting.is_healthy());
    assert!(!ServiceStatus::Error.is_healthy());
    assert!(!ServiceStatus::Stopped.is_healthy());
}

#[test]
fn test_service_status_available() {
    assert!(ServiceStatus::Running.is_available());
    assert!(ServiceStatus::Degraded.is_available());
    assert!(!ServiceStatus::Stopped.is_available());
    assert!(!ServiceStatus::Error.is_available());
}

#[test]
fn test_market_regime_variants() {
    assert_eq!(MarketRegime::Normal.to_string(), "Normal");
    assert_eq!(MarketRegime::Crisis.to_string(), "Crisis");
    assert_eq!(MarketRegime::Bull.to_string(), "Bull");
    assert_eq!(MarketRegime::Bear.to_string(), "Bear");
    assert_eq!(MarketRegime::HighVolatility.to_string(), "HighVolatility");

    // Custom variant
    let custom = MarketRegime::Custom(42);
    assert_eq!(custom.to_string(), "Custom(42)");
}

#[test]
fn test_exchange_from_str() {
    assert_eq!(Exchange::from_str("NYSE").unwrap(), Exchange::NYSE);
    assert_eq!(Exchange::from_str("nasdaq").unwrap(), Exchange::NASDAQ);
    assert_eq!(Exchange::from_str("NasDaQ").unwrap(), Exchange::NASDAQ); // Case insensitive

    // Unknown exchange
    assert_eq!(
        Exchange::from_str("UNKNOWN_EXCHANGE").unwrap(),
        Exchange::UNKNOWN
    );
}

#[test]
fn test_connection_status_variants() {
    let status = ConnectionStatus::Connected;
    assert!(matches!(status, ConnectionStatus::Connected));

    let status = ConnectionStatus::Disconnected;
    assert!(matches!(status, ConnectionStatus::Disconnected));
}

#[test]
fn test_data_type_variants() {
    let dt = DataType::Quotes;
    assert!(matches!(dt, DataType::Quotes));

    let dt = DataType::Level2;
    assert!(matches!(dt, DataType::Level2));
}

// =============================================================================
// MODULE D: COMPLEX STRUCTS - Order, Position, Execution (22 tests)
// =============================================================================

#[test]
fn test_order_construction() {
    let symbol = Symbol::from("AAPL");
    let qty = Quantity::from_f64(100.0).unwrap();
    let price = Price::from_f64(150.0).unwrap();

    let order = Order::new(symbol, OrderSide::Buy, qty, Some(price), OrderType::Limit);

    assert_eq!(order.side, OrderSide::Buy);
    assert_eq!(order.quantity, qty);
    assert_eq!(order.price, Some(price));
    assert_eq!(order.status, OrderStatus::Created);
    assert_eq!(order.filled_quantity, Quantity::ZERO);
    assert_eq!(order.remaining_quantity, qty);
}

#[test]
fn test_order_limit_constructor() {
    let symbol = Symbol::from("MSFT");
    let qty = Quantity::from_f64(50.0).unwrap();
    let price = Price::from_f64(300.0).unwrap();

    let order = Order::limit(symbol, OrderSide::Sell, qty, price);

    assert_eq!(order.order_type, OrderType::Limit);
    assert_eq!(order.price, Some(price));
}

#[test]
fn test_order_market_constructor() {
    let symbol = Symbol::from("TSLA");
    let qty = Quantity::from_f64(25.0).unwrap();

    let order = Order::market(symbol.clone(), OrderSide::Buy, qty);

    assert_eq!(order.order_type, OrderType::Market);
    assert_eq!(order.price, None);
    assert_eq!(order.symbol, symbol);
}

#[test]
fn test_order_builder_pattern() {
    let symbol = Symbol::from("GOOGL");
    let qty = Quantity::from_f64(10.0).unwrap();
    let price = Price::from_f64(2800.0).unwrap();

    let order = Order::limit(symbol, OrderSide::Buy, qty, price)
        .with_client_order_id("CLIENT-123".to_owned())
        .with_account_id("ACC-456".to_owned())
        .with_time_in_force(TimeInForce::GoodTillCancel);

    assert_eq!(order.client_order_id, Some("CLIENT-123".to_owned()));
    assert_eq!(order.account_id, Some("ACC-456".to_owned()));
    assert_eq!(order.time_in_force, TimeInForce::GoodTillCancel);
}

#[test]
fn test_order_fill_partial() {
    let symbol = Symbol::from("AAPL");
    let qty = Quantity::from_f64(100.0).unwrap();
    let price = Price::from_f64(150.0).unwrap();

    let mut order = Order::limit(symbol, OrderSide::Buy, qty, price);

    // Fill 30 shares
    let fill_qty = Quantity::from_f64(30.0).unwrap();
    let fill_price = Price::from_f64(150.5).unwrap();
    let result = order.fill(fill_qty, fill_price);

    assert!(result.is_ok());
    assert_eq!(order.filled_quantity, fill_qty);
    assert_eq!(order.remaining_quantity, Quantity::from_f64(70.0).unwrap());
    assert_eq!(order.status, OrderStatus::PartiallyFilled);
    assert_eq!(order.average_price, Some(fill_price));
}

#[test]
fn test_order_fill_complete() {
    let symbol = Symbol::from("AAPL");
    let qty = Quantity::from_f64(50.0).unwrap();
    let price = Price::from_f64(150.0).unwrap();

    let mut order = Order::limit(symbol, OrderSide::Buy, qty, price);

    // Fill all 50 shares
    let result = order.fill(qty, price);

    assert!(result.is_ok());
    assert!(order.is_filled());
    assert_eq!(order.status, OrderStatus::Filled);
    assert_eq!(order.remaining_quantity, Quantity::ZERO);
}

#[test]
fn test_order_fill_multiple() {
    let symbol = Symbol::from("AAPL");
    let qty = Quantity::from_f64(100.0).unwrap();
    let price = Price::from_f64(150.0).unwrap();

    let mut order = Order::limit(symbol, OrderSide::Buy, qty, price);

    // First fill: 30 shares at $150.50
    order
        .fill(
            Quantity::from_f64(30.0).unwrap(),
            Price::from_f64(150.5).unwrap(),
        )
        .unwrap();

    // Second fill: 40 shares at $150.25
    order
        .fill(
            Quantity::from_f64(40.0).unwrap(),
            Price::from_f64(150.25).unwrap(),
        )
        .unwrap();

    // Third fill: 30 shares at $150.75
    order
        .fill(
            Quantity::from_f64(30.0).unwrap(),
            Price::from_f64(150.75).unwrap(),
        )
        .unwrap();

    assert!(order.is_filled());

    // Average price should be weighted average
    let avg = order.average_price.unwrap();
    // (30*150.5 + 40*150.25 + 30*150.75) / 100 = 150.475
    assert!((avg.to_f64() - 150.475).abs() < 0.01);
}

#[test]
fn test_order_fill_overfill_rejection() {
    let symbol = Symbol::from("AAPL");
    let qty = Quantity::from_f64(50.0).unwrap();
    let price = Price::from_f64(150.0).unwrap();

    let mut order = Order::limit(symbol, OrderSide::Buy, qty, price);

    // Try to fill more than order quantity
    let overfill_qty = Quantity::from_f64(60.0).unwrap();
    let result = order.fill(overfill_qty, price);

    assert!(result.is_err());
}

#[test]
fn test_order_fill_percentage() {
    let symbol = Symbol::from("AAPL");
    let qty = Quantity::from_f64(100.0).unwrap();
    let price = Price::from_f64(150.0).unwrap();

    let mut order = Order::limit(symbol, OrderSide::Buy, qty, price);

    assert_eq!(order.fill_percentage(), 0.0);

    order
        .fill(Quantity::from_f64(25.0).unwrap(), price)
        .unwrap();
    assert!((order.fill_percentage() - 25.0).abs() < 0.01);

    order
        .fill(Quantity::from_f64(25.0).unwrap(), price)
        .unwrap();
    assert!((order.fill_percentage() - 50.0).abs() < 0.01);

    order
        .fill(Quantity::from_f64(50.0).unwrap(), price)
        .unwrap();
    assert!((order.fill_percentage() - 100.0).abs() < 0.01);
}

#[test]
fn test_order_is_partially_filled() {
    let symbol = Symbol::from("AAPL");
    let qty = Quantity::from_f64(100.0).unwrap();
    let price = Price::from_f64(150.0).unwrap();

    let mut order = Order::limit(symbol, OrderSide::Buy, qty, price);

    assert!(!order.is_partially_filled());

    order
        .fill(Quantity::from_f64(50.0).unwrap(), price)
        .unwrap();
    assert!(order.is_partially_filled());

    order
        .fill(Quantity::from_f64(50.0).unwrap(), price)
        .unwrap();
    assert!(!order.is_partially_filled()); // Now fully filled
}

#[test]
fn test_position_creation() {
    let pos = Position::new(
        "AAPL".to_owned(),
        Decimal::from(100),
        Decimal::from_str("150.50").unwrap(),
    );

    assert_eq!(pos.symbol, "AAPL");
    assert_eq!(pos.quantity, Decimal::from(100));
    assert_eq!(pos.avg_price, Decimal::from_str("150.50").unwrap());
    assert_eq!(pos.unrealized_pnl, Decimal::ZERO);
    assert_eq!(pos.realized_pnl, Decimal::ZERO);
}

#[test]
fn test_position_is_long() {
    let pos = Position::new(
        "AAPL".to_owned(),
        Decimal::from(100),
        Decimal::from_str("150.0").unwrap(),
    );
    assert!(pos.is_long());
    assert!(!pos.is_short());
}

#[test]
fn test_position_is_short() {
    let pos = Position::new(
        "AAPL".to_owned(),
        Decimal::from(-50),
        Decimal::from_str("150.0").unwrap(),
    );
    assert!(pos.is_short());
    assert!(!pos.is_long());
}

#[test]
fn test_position_unrealized_pnl_long() {
    let mut pos = Position::new(
        "AAPL".to_owned(),
        Decimal::from(100),
        Decimal::from_str("150.0").unwrap(),
    );

    // Price goes up to $160
    pos.calculate_unrealized_pnl(Decimal::from_str("160.0").unwrap());

    // P&L = 100 * (160 - 150) = 1000
    assert_eq!(pos.unrealized_pnl, Decimal::from(1000));
}

#[test]
fn test_position_unrealized_pnl_short() {
    let mut pos = Position::new(
        "AAPL".to_owned(),
        Decimal::from(-100),
        Decimal::from_str("150.0").unwrap(),
    );

    // Price goes up to $160 (bad for short)
    pos.calculate_unrealized_pnl(Decimal::from_str("160.0").unwrap());

    // P&L = -100 * (150 - 160) = 1000 loss
    assert_eq!(pos.unrealized_pnl, Decimal::from(-1000));
}

#[test]
fn test_position_roi_percentage() {
    let mut pos = Position::new(
        "AAPL".to_owned(),
        Decimal::from(100),
        Decimal::from_str("150.0").unwrap(),
    );
    pos.calculate_unrealized_pnl(Decimal::from_str("165.0").unwrap());

    // ROI = (1500 / 15000) * 100 = 10%
    let roi = pos.roi_percentage();
    assert!((roi - Decimal::from(10)).abs() < Decimal::from_str("0.01").unwrap());
}

#[test]
fn test_execution_creation() {
    let order_id = uuid::Uuid::new_v4();
    let exec = Execution::new(
        order_id,
        "AAPL".to_owned(),
        Decimal::from(100),
        Decimal::from_str("150.0").unwrap(),
        OrderSide::Buy,
        Decimal::from_str("1.50").unwrap(),
    );

    assert_eq!(exec.order_id, order_id);
    assert_eq!(exec.symbol, "AAPL");
    assert_eq!(exec.quantity, Decimal::from(100));
    assert_eq!(exec.price, Decimal::from_str("150.0").unwrap());
    assert_eq!(exec.fees, Decimal::from_str("1.50").unwrap());
}

#[test]
fn test_execution_gross_net_value_buy() {
    let order_id = uuid::Uuid::new_v4();
    let exec = Execution::new(
        order_id,
        "AAPL".to_owned(),
        Decimal::from(100),
        Decimal::from_str("150.0").unwrap(),
        OrderSide::Buy,
        Decimal::from_str("10.0").unwrap(),
    );

    // Gross = 100 * 150 = 15000
    assert_eq!(exec.gross_value, Decimal::from(15000));

    // Net (buy) = gross + fees = 15010
    assert_eq!(exec.net_value, Decimal::from(15010));
}

#[test]
fn test_execution_gross_net_value_sell() {
    let order_id = uuid::Uuid::new_v4();
    let exec = Execution::new(
        order_id,
        "AAPL".to_owned(),
        Decimal::from(100),
        Decimal::from_str("150.0").unwrap(),
        OrderSide::Sell,
        Decimal::from_str("10.0").unwrap(),
    );

    // Gross = 100 * 150 = 15000
    assert_eq!(exec.gross_value, Decimal::from(15000));

    // Net (sell) = gross - fees = 14990
    assert_eq!(exec.net_value, Decimal::from(14990));
}

#[test]
fn test_execution_effective_price() {
    let order_id = uuid::Uuid::new_v4();
    let exec = Execution::new(
        order_id,
        "AAPL".to_owned(),
        Decimal::from(100),
        Decimal::from_str("150.0").unwrap(),
        OrderSide::Buy,
        Decimal::from_str("50.0").unwrap(),
    );

    // Effective price = (15000 + 50) / 100 = 150.50
    let eff_price = exec.effective_price();
    assert!(
        (eff_price - Decimal::from_str("150.50").unwrap()).abs()
            < Decimal::from_str("0.01").unwrap()
    );
}

// =============================================================================
// MODULE E: MARKET DATA TYPES (10 tests)
// =============================================================================

#[test]
fn test_quote_event_creation() {
    let now = Utc::now();
    let quote = QuoteEvent::new("AAPL".to_owned(), now);

    assert_eq!(quote.symbol, "AAPL");
    assert_eq!(quote.timestamp, now);
    assert_eq!(quote.bid, None);
    assert_eq!(quote.ask, None);
}

#[test]
fn test_quote_event_builder() {
    let now = Utc::now();
    let bid_price = Decimal::from_str("150.00").unwrap();
    let ask_price = Decimal::from_str("150.05").unwrap();

    let quote = QuoteEvent::new("AAPL".to_owned(), now)
        .with_bid(bid_price, Decimal::from(100))
        .with_ask(ask_price, Decimal::from(50))
        .with_exchange("NYSE")
        .with_sequence(12345);

    assert_eq!(quote.bid, Some(bid_price));
    assert_eq!(quote.ask, Some(ask_price));
    assert_eq!(quote.exchange, Some("NYSE".to_owned()));
    assert_eq!(quote.sequence, 12345);
}

#[test]
fn test_quote_event_mid_price() {
    let now = Utc::now();
    let quote = QuoteEvent::new("AAPL".to_owned(), now)
        .with_bid(Decimal::from(150), Decimal::from(100))
        .with_ask(Decimal::from(151), Decimal::from(50));

    let mid = quote.mid_price().unwrap();
    assert_eq!(mid, Decimal::from_str("150.5").unwrap());
}

#[test]
fn test_quote_event_spread() {
    let now = Utc::now();
    let quote = QuoteEvent::new("AAPL".to_owned(), now)
        .with_bid(Decimal::from(150), Decimal::from(100))
        .with_ask(Decimal::from_str("150.05").unwrap(), Decimal::from(50));

    let spread = quote.spread().unwrap();
    assert_eq!(spread, Decimal::from_str("0.05").unwrap());
}

#[test]
fn test_trade_event_creation() {
    let now = Utc::now();
    let trade = TradeEvent::new(
        "AAPL".to_owned(),
        Decimal::from_str("150.50").unwrap(),
        Decimal::from(100),
        now,
    );

    assert_eq!(trade.symbol, "AAPL");
    assert_eq!(trade.price, Decimal::from_str("150.50").unwrap());
    assert_eq!(trade.size, Decimal::from(100));
}

#[test]
fn test_trade_event_notional_value() {
    let now = Utc::now();
    let trade = TradeEvent::new(
        "AAPL".to_owned(),
        Decimal::from(150),
        Decimal::from(100),
        now,
    );

    assert_eq!(trade.notional_value(), Decimal::from(15000));
}

#[test]
fn test_market_data_event_symbol_accessor() {
    let now = Utc::now();
    let quote = QuoteEvent::new("AAPL".to_owned(), now);
    let event = MarketDataEvent::Quote(quote);

    assert_eq!(event.symbol(), "AAPL");
}

#[test]
fn test_market_data_event_timestamp_accessor() {
    let now = Utc::now();
    let trade = TradeEvent::new(
        "MSFT".to_owned(),
        Decimal::from(300),
        Decimal::from(50),
        now,
    );
    let event = MarketDataEvent::Trade(trade);

    assert_eq!(event.timestamp(), Some(now));
}

#[test]
fn test_connection_info_url_generation() {
    let conn = ConnectionInfo::new("localhost", 50051);
    assert_eq!(conn.url(), "http://localhost:50051");

    let conn_tls = conn.with_tls();
    assert_eq!(conn_tls.url(), "https://localhost:50051");
}

#[test]
fn test_money_display() {
    let money = Money::new(Decimal::from_str("1234.56").unwrap(), Currency::USD);
    let display = format!("{}", money);

    assert!(display.contains("1234.56"));
    assert!(display.contains("USD"));
}

// =============================================================================
// MODULE F: ERROR HANDLING & EDGE CASES (10 tests)
// =============================================================================

#[test]
fn test_common_type_error_variants() {
    let err1 = CommonTypeError::InvalidPrice {
        value: "-10.0".to_owned(),
        reason: "Negative price".to_owned(),
    };
    assert!(format!("{}", err1).contains("Invalid price"));

    let err2 = CommonTypeError::InvalidQuantity {
        value: "-5.0".to_owned(),
        reason: "Negative quantity".to_owned(),
    };
    assert!(format!("{}", err2).contains("Invalid quantity"));

    let err3 = CommonTypeError::ValidationError {
        field: "symbol".to_owned(),
        reason: "Empty symbol".to_owned(),
    };
    assert!(format!("{}", err3).contains("Validation error"));
}

#[test]
fn test_common_type_error_clone() {
    let err1 = CommonTypeError::InvalidPrice {
        value: "100".to_owned(),
        reason: "test".to_owned(),
    };
    let err2 = err1.clone();

    assert_eq!(err1, err2);

    // IO/JSON errors should clone to ConversionError
    let io_err = CommonTypeError::IoError(std::io::Error::new(
        std::io::ErrorKind::NotFound,
        "file not found",
    ));
    let cloned = io_err.clone();

    assert!(matches!(cloned, CommonTypeError::ConversionError { .. }));
}

#[test]
fn test_common_type_error_partial_eq() {
    let err1 = CommonTypeError::InvalidPrice {
        value: "100".to_owned(),
        reason: "test".to_owned(),
    };
    let err2 = CommonTypeError::InvalidPrice {
        value: "100".to_owned(),
        reason: "test".to_owned(),
    };

    assert_eq!(err1, err2);

    let err3 = CommonTypeError::InvalidPrice {
        value: "200".to_owned(),
        reason: "test".to_owned(),
    };

    assert_ne!(err1, err3);
}

#[test]
fn test_hft_timestamp_now() {
    let ts = HftTimestamp::now();
    assert!(ts.is_ok());

    let timestamp = ts.unwrap();
    assert!(timestamp.nanos() > 0);
}

#[test]
fn test_hft_timestamp_now_or_zero() {
    let ts = HftTimestamp::now_or_zero();
    assert!(ts.nanos() > 0);
}

#[test]
fn test_hft_timestamp_from_nanos() {
    let ts = HftTimestamp::from_nanos(1_000_000_000);
    assert_eq!(ts.nanos(), 1_000_000_000);
}

#[test]
fn test_hft_timestamp_to_datetime() {
    let ts = HftTimestamp::from_nanos(1_609_459_200_000_000_000); // 2021-01-01 00:00:00 UTC
    let dt = ts.to_datetime();

    assert_eq!(dt.year(), 2021);
    assert_eq!(dt.month(), 1);
    assert_eq!(dt.day(), 1);
}

#[test]
fn test_trading_signal_validation() {
    let symbol = Symbol::from("AAPL");

    // Valid signal
    let signal = TradingSignal::new(
        symbol.clone(),
        0.75,
        OrderSide::Buy,
        0.85,
        "ML_MODEL_1".to_owned(),
    );
    assert!(signal.is_ok());

    // Invalid confidence (> 1.0)
    let invalid_conf = TradingSignal::new(
        symbol.clone(),
        0.75,
        OrderSide::Buy,
        1.5,
        "ML_MODEL_1".to_owned(),
    );
    assert!(invalid_conf.is_err());

    // Invalid strength (< -1.0)
    let invalid_strength =
        TradingSignal::new(symbol, -1.5, OrderSide::Buy, 0.85, "ML_MODEL_1".to_owned());
    assert!(invalid_strength.is_err());
}

#[test]
fn test_account_id_validation() {
    let valid = AccountId::new("ACC-12345");
    assert!(valid.is_ok());

    let empty = AccountId::new("");
    assert!(empty.is_err());

    let whitespace = AccountId::new("   ");
    assert!(whitespace.is_err());
}

#[test]
fn test_order_ref_copy_semantics() {
    let price = Price::from_f64(150.0).unwrap();
    let qty = Quantity::from_f64(100.0).unwrap();
    let order = Order::limit(Symbol::from("AAPL"), OrderSide::Buy, qty, price);

    let order_ref = OrderRef::from_order(&order);

    // OrderRef should be Copy
    let ref_copy = order_ref;
    assert_eq!(order_ref.id, ref_copy.id);
    assert_eq!(order_ref.quantity, ref_copy.quantity);
}

// =============================================================================
// MODULE G: SERIALIZATION TESTS (12 tests)
// =============================================================================

#[test]
fn test_price_json_serialization() {
    let price = Price::from_f64(123.45).unwrap();

    let json = serde_json::to_string(&price).unwrap();
    let deserialized: Price = serde_json::from_str(&json).unwrap();

    assert_eq!(price, deserialized);
}

#[test]
fn test_quantity_json_serialization() {
    let qty = Quantity::from_f64(999.99).unwrap();

    let json = serde_json::to_string(&qty).unwrap();
    let deserialized: Quantity = serde_json::from_str(&json).unwrap();

    assert_eq!(qty, deserialized);
}

#[test]
fn test_order_json_serialization() {
    let symbol = Symbol::from("AAPL");
    let qty = Quantity::from_f64(100.0).unwrap();
    let price = Price::from_f64(150.0).unwrap();
    let order = Order::limit(symbol, OrderSide::Buy, qty, price);

    let json = serde_json::to_string(&order).unwrap();
    let deserialized: Order = serde_json::from_str(&json).unwrap();

    assert_eq!(order.symbol, deserialized.symbol);
    assert_eq!(order.quantity, deserialized.quantity);
    assert_eq!(order.side, deserialized.side);
}

#[test]
fn test_order_type_json_serialization() {
    let order_type = OrderType::Limit;

    let json = serde_json::to_string(&order_type).unwrap();
    let deserialized: OrderType = serde_json::from_str(&json).unwrap();

    assert_eq!(order_type, deserialized);
}

#[test]
fn test_order_status_json_serialization() {
    let status = OrderStatus::PartiallyFilled;

    let json = serde_json::to_string(&status).unwrap();
    let deserialized: OrderStatus = serde_json::from_str(&json).unwrap();

    assert_eq!(status, deserialized);
}

#[test]
fn test_currency_json_serialization() {
    let currency = Currency::EUR;

    let json = serde_json::to_string(&currency).unwrap();
    let deserialized: Currency = serde_json::from_str(&json).unwrap();

    assert_eq!(currency, deserialized);
}

#[test]
fn test_quote_event_json_serialization() {
    let now = Utc::now();
    let quote = QuoteEvent::new("AAPL".to_owned(), now)
        .with_bid(Decimal::from(150), Decimal::from(100))
        .with_ask(Decimal::from(151), Decimal::from(50));

    let json = serde_json::to_string(&quote).unwrap();
    let deserialized: QuoteEvent = serde_json::from_str(&json).unwrap();

    assert_eq!(quote, deserialized);
}

#[test]
fn test_trade_event_json_serialization() {
    let now = Utc::now();
    let trade = TradeEvent::new(
        "MSFT".to_owned(),
        Decimal::from(300),
        Decimal::from(50),
        now,
    );

    let json = serde_json::to_string(&trade).unwrap();
    let deserialized: TradeEvent = serde_json::from_str(&json).unwrap();

    assert_eq!(trade.symbol, deserialized.symbol);
    assert_eq!(trade.price, deserialized.price);
    assert_eq!(trade.size, deserialized.size);
}

#[test]
fn test_market_regime_json_serialization() {
    let regime = MarketRegime::Bull;

    let json = serde_json::to_string(&regime).unwrap();
    let deserialized: MarketRegime = serde_json::from_str(&json).unwrap();

    assert_eq!(regime, deserialized);

    // Test custom variant
    let custom = MarketRegime::Custom(42);
    let json = serde_json::to_string(&custom).unwrap();
    let deserialized: MarketRegime = serde_json::from_str(&json).unwrap();

    assert_eq!(custom, deserialized);
}

#[test]
fn test_invalid_json_deserialization() {
    // Invalid OrderType
    let result: Result<OrderType, _> = serde_json::from_str("\"INVALID_TYPE\"");
    assert!(result.is_err());

    // Invalid Currency
    let result: Result<Currency, _> = serde_json::from_str("\"INVALID_CURRENCY\"");
    assert!(result.is_err());
}

#[test]
fn test_common_type_error_serialization() {
    let err = CommonTypeError::ValidationError {
        field: "test_field".to_owned(),
        reason: "test reason".to_owned(),
    };

    let json = serde_json::to_string(&err).unwrap();
    let deserialized: CommonTypeError = serde_json::from_str(&json).unwrap();

    // Should deserialize as ConversionError (per custom implementation)
    assert!(matches!(
        deserialized,
        CommonTypeError::ConversionError { .. }
    ));
}

#[test]
fn test_symbol_comparison_with_string() {
    let sym = Symbol::from("AAPL");

    assert_eq!(sym, "AAPL");
    assert_eq!(sym, "AAPL".to_owned());
    assert_ne!(sym, "MSFT");

    assert_eq!("AAPL", sym);
    assert_eq!("AAPL".to_owned(), sym);
}

// =============================================================================
// MODULE H: ADDITIONAL EDGE CASES & INTEGRATIONS (10 tests)
// =============================================================================

#[test]
fn test_price_max_saturation() {
    let max_price = Price::MAX;
    let one = Price::ONE;

    // Adding to MAX should saturate
    let result = max_price + one;
    assert_eq!(result, Price::MAX);
}

#[test]
fn test_quantity_zero_saturation() {
    let zero_qty = Quantity::ZERO;
    let one = Quantity::ONE;

    // Subtracting from ZERO should saturate
    let result = zero_qty - one;
    assert_eq!(result, Quantity::ZERO);
}

#[test]
fn test_order_fill_zero_quantity() {
    let symbol = Symbol::from("AAPL");
    let qty = Quantity::from_f64(100.0).unwrap();
    let price = Price::from_f64(150.0).unwrap();

    let _order = Order::limit(symbol, OrderSide::Buy, qty, price);

    // Create zero-quantity order for fill percentage calculation
    let zero_order = Order::limit(Symbol::from("TEST"), OrderSide::Buy, Quantity::ZERO, price);
    assert_eq!(zero_order.fill_percentage(), 0.0);
}

#[test]
fn test_position_zero_notional() {
    let pos = Position::new("AAPL".to_owned(), Decimal::ZERO, Decimal::from(150));

    // ROI should be zero for zero position
    assert_eq!(pos.roi_percentage(), Decimal::ZERO);
}

#[test]
fn test_execution_zero_quantity() {
    let order_id = uuid::Uuid::new_v4();
    let exec = Execution::new(
        order_id,
        "AAPL".to_owned(),
        Decimal::ZERO,
        Decimal::from(150),
        OrderSide::Buy,
        Decimal::ZERO,
    );

    // Effective price should equal price for zero quantity
    assert_eq!(exec.effective_price(), Decimal::from(150));
}

#[test]
fn test_config_version_creation() {
    let version = ConfigVersion::new(1);

    assert_eq!(version.version, 1);
    assert!(version.description.is_none());

    let version_with_desc = ConfigVersion::with_description(2, "Updated config");
    assert_eq!(version_with_desc.version, 2);
    assert_eq!(
        version_with_desc.description,
        Some("Updated config".to_owned())
    );
}

#[test]
fn test_request_id_generation() {
    let id1 = RequestId::new();
    let id2 = RequestId::new();

    // Should generate unique UUIDs
    assert_ne!(id1, id2);
}

#[test]
fn test_event_id_empty_string() {
    let id = EventId::from_string("");

    // Empty string should generate new UUID
    assert!(!id.value().is_empty());
}

#[test]
fn test_subscription_creation() {
    let sub = Subscription {
        symbols: vec!["AAPL".to_owned(), "MSFT".to_owned()],
        data_types: vec![DataType::Trades, DataType::Quotes],
        exchanges: vec!["NYSE".to_owned()],
    };

    assert_eq!(sub.symbols.len(), 2);
    assert_eq!(sub.data_types.len(), 2);
}

#[test]
fn test_resource_limits_default() {
    let limits = ResourceLimits::default();

    assert_eq!(limits.max_memory_bytes, None);
    assert_eq!(limits.max_cpu_percent, None);
    assert_eq!(limits.max_file_descriptors, None);
    assert_eq!(limits.max_connections, None);
}

// =============================================================================
// FINAL TEST COUNT: 82 comprehensive test functions
// File size: ~1,750 lines with comprehensive coverage
// =============================================================================
