//! Real market data replay infrastructure
//!
//! This module provides comprehensive infrastructure for loading and replaying
//! real market data from Parquet files. It's designed for use across multiple
//! contexts: tests, benchmarks, backtesting, and ML training.
//!
//! # Architecture
//!
//! ```text
//! ┌─────────────────────┐
//! │  Parquet Files      │
//! │  (Historical Data)  │
//! └──────────┬──────────┘
//!            │
//!            ▼
//! ┌─────────────────────┐
//! │  ParquetDataLoader  │  ← Load data from Parquet
//! │  - Bulk loading     │
//! │  - Streaming        │
//! └──────────┬──────────┘
//!            │
//!            ▼
//! ┌─────────────────────┐
//! │ MarketDataStreamer  │  ← Time-accurate replay
//! │  - Speed control    │
//! │  - Timing accuracy  │
//! └──────────┬──────────┘
//!            │
//!            ▼
//! ┌─────────────────────┐
//! │   Consumers         │
//! │  - Tests            │
//! │  - Benchmarks       │
//! │  - Backtesting      │
//! │  - ML Training      │
//! └─────────────────────┘
//! ```
//!
//! # Core Components
//!
//! ## ParquetDataLoader
//!
//! Efficient Parquet file loading with two modes:
//! - **Bulk loading**: Load entire file into memory for random access
//! - **Streaming**: Process events batch-by-batch for memory efficiency
//!
//! ## MarketDataStreamer
//!
//! Time-accurate replay of historical data with:
//! - Preserved timing relationships between events
//! - Configurable speed multipliers (1x, 10x, 100x, etc.)
//! - Backpressure-safe async channels
//!
//! # Usage Examples
//!
//! ## Basic: Load and Stream Real Data
//!
//! ```no_run
//! use data::replay::{ParquetDataLoader, MarketDataStreamer};
//!
//! # async fn example() -> anyhow::Result<()> {
//! // Load market data from Parquet file
//! let loader = ParquetDataLoader::new("test_data/real/parquet/ES.FUT_ohlcv-1m_2024-01-02.parquet");
//! let events = loader.load_all().await?;
//!
//! println!("Loaded {} events", events.len());
//!
//! // Stream events at real-time speed
//! let streamer = MarketDataStreamer::new(events);
//! let mut rx = streamer.stream().await;
//!
//! while let Some(event) = rx.recv().await {
//!     println!("Event: {:?} at {}", event.event_type, event.timestamp_ns);
//! }
//! # Ok(())
//! # }
//! ```
//!
//! ## Fast Backtesting: 10x Speed
//!
//! ```no_run
//! use data::replay::{ParquetDataLoader, MarketDataStreamer};
//!
//! # async fn example() -> anyhow::Result<()> {
//! let loader = ParquetDataLoader::new("test_data/real/parquet/ES.FUT_ohlcv-1m_2024-01-02.parquet");
//! let events = loader.load_all().await?;
//!
//! // 10x faster replay for quick backtesting
//! let streamer = MarketDataStreamer::new(events)
//!     .with_speed(10.0)
//!     .with_buffer_size(10000);
//!
//! let mut rx = streamer.stream().await;
//!
//! // Process events 10x faster than real-time
//! while let Some(event) = rx.recv().await {
//!     // Your backtest logic here
//! }
//! # Ok(())
//! # }
//! ```
//!
//! ## ML Training: Instant Replay (No Delays)
//!
//! ```no_run
//! use data::replay::{ParquetDataLoader, MarketDataStreamer};
//!
//! # async fn example() -> anyhow::Result<()> {
//! let loader = ParquetDataLoader::new("test_data/real/parquet/ES.FUT_ohlcv-1m_2024-01-02.parquet");
//! let events = loader.load_all().await?;
//!
//! // Instant replay (no timing delays)
//! let streamer = MarketDataStreamer::new(events)
//!     .with_speed(f64::INFINITY);
//!
//! let mut rx = streamer.stream().await;
//!
//! // Process events as fast as possible for ML training
//! while let Some(event) = rx.recv().await {
//!     // Feature extraction, model training, etc.
//! }
//! # Ok(())
//! # }
//! ```
//!
//! ## Memory-Efficient Streaming
//!
//! ```no_run
//! use data::replay::ParquetDataLoader;
//!
//! # async fn example() -> anyhow::Result<()> {
//! let loader = ParquetDataLoader::new("large_dataset.parquet");
//! let mut stream = loader.load_stream().await?;
//!
//! // Process batches without loading entire file into memory
//! while let Some(batch) = stream.next().await {
//!     let events = batch?;
//!     println!("Processing batch of {} events", events.len());
//!     // Process batch...
//! }
//! # Ok(())
//! # }
//! ```
//!
//! ## Integration with Benchmarks
//!
//! ```no_run
//! use criterion::{criterion_group, criterion_main, Criterion};
//! use data::replay::{ParquetDataLoader, MarketDataStreamer};
//!
//! async fn load_test_data() -> Vec<trading_engine::types::metrics::ParquetMarketDataEvent> {
//!     let loader = ParquetDataLoader::new("test_data/real/parquet/ES.FUT_ohlcv-1m_2024-01-02.parquet");
//!     loader.load_all().await.expect("Failed to load test data")
//! }
//!
//! fn benchmark_strategy(c: &mut Criterion) {
//!     let rt = tokio::runtime::Runtime::new().unwrap();
//!     let events = rt.block_on(load_test_data());
//!
//!     c.bench_function("strategy_with_real_data", |b| {
//!         b.to_async(&rt).iter(|| async {
//!             let streamer = MarketDataStreamer::new(events.clone())
//!                 .with_speed(f64::INFINITY); // Instant for benchmarking
//!             let mut rx = streamer.stream().await;
//!
//!             while let Some(event) = rx.recv().await {
//!                 // Your strategy logic
//!             }
//!         });
//!     });
//! }
//!
//! criterion_group!(benches, benchmark_strategy);
//! criterion_main!(benches);
//! ```
//!
//! ## Integration with Tests
//!
//! ```no_run
//! #[cfg(test)]
//! mod tests {
//!     use data::replay::{ParquetDataLoader, MarketDataStreamer};
//!
//!     #[tokio::test]
//!     async fn test_strategy_with_real_data() {
//!         // Load real market data
//!         let loader = ParquetDataLoader::new("test_data/real/parquet/ES.FUT_ohlcv-1m_2024-01-02.parquet");
//!         let events = loader.load_all().await.expect("Failed to load test data");
//!
//!         // Stream at high speed for tests
//!         let streamer = MarketDataStreamer::new(events)
//!             .with_speed(100.0); // 100x faster
//!
//!         let mut rx = streamer.stream().await;
//!
//!         let mut processed_count = 0;
//!         while let Some(event) = rx.recv().await {
//!             // Test your strategy logic
//!             processed_count += 1;
//!         }
//!
//!         assert!(processed_count > 0, "Should process events");
//!     }
//! }
//! ```
//!
//! # Performance Characteristics
//!
//! ## ParquetDataLoader
//! - **Bulk loading**: O(n) time, O(n) memory
//! - **Streaming**: O(1) memory per batch, amortized O(n) time
//! - **Throughput**: ~1-5M events/sec depending on schema complexity
//!
//! ## MarketDataStreamer
//! - **Latency**: < 1μs per event (excluding intentional delays)
//! - **Throughput**: Limited by channel buffer and consumer speed
//! - **Memory**: O(buffer_size) for channel, O(1) for streamer
//!
//! # File Format
//!
//! Expected Parquet schema (all fields from ParquetMarketDataEvent):
//! - `timestamp_ns`: Timestamp (nanoseconds) - REQUIRED
//! - `symbol`: String - REQUIRED
//! - `venue`: String - REQUIRED
//! - `event_type`: String (Trade/Quote/OrderBookUpdate/StatusUpdate/Ohlcv) - REQUIRED
//! - `sequence`: UInt64 - REQUIRED
//! - `price`: Float64 - OPTIONAL
//! - `quantity`: Float64 - OPTIONAL
//! - `latency_ns`: UInt64 - OPTIONAL
//! - `open`: Float64 - OPTIONAL (OHLCV only)
//! - `high`: Float64 - OPTIONAL (OHLCV only)
//! - `low`: Float64 - OPTIONAL (OHLCV only)

pub mod market_data_streamer;
pub mod parquet_loader;

pub use market_data_streamer::MarketDataStreamer;
pub use parquet_loader::{ParquetDataLoader, ParquetEventStream};

// Re-export the event type for convenience
pub use trading_engine::types::metrics::ParquetMarketDataEvent;
