//! # Databento Types - Production Market Data Structures
//!
//! Comprehensive type definitions for Databento's market data ecosystem.
//! Optimized for zero-copy operations and ultra-low latency HFT processing.
//!
//! ## Performance Optimizations
//!
//! - **Zero-Copy Deserialization**: Direct memory mapping with minimal allocations
//! - **Cache-Friendly Layouts**: Packed structs aligned for CPU cache lines
//! - **SIMD-Ready Data**: Aligned arrays for vectorized operations
//! - **Lock-Free Operations**: Atomic operations for concurrent access
//!
//! ## Data Coverage
//!
//! - **Market Microstructure**: L1/L2/L3 order books, trades, quotes
//! - **Aggregate Data**: OHLCV bars, statistics, session summaries
//! - **Reference Data**: Instruments, publishers, symbology mappings
//! - **Control Messages**: Authentication, subscriptions, heartbeats, errors

use chrono::{DateTime, Utc};
use common::Symbol;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::time::Duration;

/// Primary configuration for `Databento` integration
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DatabentoConfig {
    /// API key for authentication
    pub api_key: String,
    /// Environment selection (production, testing)
    pub environment: DatabentoEnvironment,
    /// WebSocket configuration
    pub websocket: DatabentoWebSocketConfig,
    /// Historical data configuration
    pub historical: DatabentoHistoricalConfig,
    /// Performance tuning parameters
    pub performance: PerformanceConfig,
    /// Monitoring and alerting settings
    pub monitoring: MonitoringConfig,
}

impl Default for DatabentoConfig {
    /// Default configuration uses testing settings for safe development
    fn default() -> Self {
        Self::testing()
    }
}

impl DatabentoConfig {
    /// Production configuration with optimized settings
    pub fn production() -> Self {
        Self {
            api_key: std::env::var("DATABENTO_API_KEY").unwrap_or_default(),
            environment: DatabentoEnvironment::Production,
            websocket: DatabentoWebSocketConfig::production(),
            historical: DatabentoHistoricalConfig::production(),
            performance: PerformanceConfig::high_frequency(),
            monitoring: MonitoringConfig::production(),
        }
    }

    /// Testing configuration with relaxed settings
    pub fn testing() -> Self {
        Self {
            api_key: std::env::var("DATABENTO_API_KEY_TEST").unwrap_or_default(),
            environment: DatabentoEnvironment::Testing,
            websocket: DatabentoWebSocketConfig::testing(),
            historical: DatabentoHistoricalConfig::testing(),
            performance: PerformanceConfig::development(),
            monitoring: MonitoringConfig::development(),
        }
    }

    /// Convert to WebSocket-specific configuration
    pub fn to_websocket_config(&self) -> super::websocket_client::DatabentoWebSocketConfig {
        super::websocket_client::DatabentoWebSocketConfig {
            api_key: self.api_key.clone(),
            endpoint: self.websocket.endpoint.clone(),
            connect_timeout_ms: self.websocket.connect_timeout_ms,
            message_timeout_ms: self.websocket.message_timeout_ms,
            max_reconnect_attempts: self.websocket.max_reconnect_attempts,
            reconnect_delay_ms: self.websocket.reconnect_delay_ms,
            max_reconnect_delay_ms: self.websocket.max_reconnect_delay_ms,
            enable_compression: self.websocket.enable_compression,
            ring_buffer_size: self.performance.ring_buffer_size,
            batch_size: self.performance.batch_size,
            enable_heartbeat: self.websocket.enable_heartbeat,
            heartbeat_interval_s: self.websocket.heartbeat_interval_s,
            max_memory_usage: self.performance.max_memory_usage,
            enable_metrics: self.monitoring.enable_detailed_metrics,
        }
    }
}

/// `Databento` environment selection
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum DatabentoEnvironment {
    /// Production environment with real market data
    Production,
    /// Testing environment with sample data
    Testing,
}

/// WebSocket-specific configuration
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DatabentoWebSocketConfig {
    /// WebSocket endpoint URL
    pub endpoint: String,
    /// Connection timeout in milliseconds
    pub connect_timeout_ms: u64,
    /// Message timeout in milliseconds
    pub message_timeout_ms: u64,
    /// Maximum reconnection attempts
    pub max_reconnect_attempts: u32,
    /// Initial reconnection delay in milliseconds
    pub reconnect_delay_ms: u64,
    /// Maximum reconnection delay in milliseconds
    pub max_reconnect_delay_ms: u64,
    /// Enable message compression
    pub enable_compression: bool,
    /// Enable heartbeat monitoring
    pub enable_heartbeat: bool,
    /// Heartbeat interval in seconds
    pub heartbeat_interval_s: u64,
}

impl DatabentoWebSocketConfig {
    pub fn production() -> Self {
        let endpoints =
            config::DatabentoEndpoints::from_env(config::DataProviderEnvironment::Production);
        Self {
            endpoint: endpoints.websocket_url,
            connect_timeout_ms: 5000,
            message_timeout_ms: 30000,
            max_reconnect_attempts: 10,
            reconnect_delay_ms: 100,
            max_reconnect_delay_ms: 30000,
            enable_compression: true,
            enable_heartbeat: true,
            heartbeat_interval_s: 30,
        }
    }

    pub fn testing() -> Self {
        Self {
            endpoint: "wss://gateway-test.databento.com/v0/subscribe".to_string(),
            connect_timeout_ms: 10000,
            message_timeout_ms: 60000,
            max_reconnect_attempts: 3,
            reconnect_delay_ms: 1000,
            max_reconnect_delay_ms: 10000,
            enable_compression: false,
            enable_heartbeat: false,
            heartbeat_interval_s: 60,
        }
    }
}

/// Historical data configuration
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DatabentoHistoricalConfig {
    /// REST API base URL
    pub base_url: String,
    /// Request timeout in seconds
    pub timeout_seconds: u64,
    /// Rate limit (requests per second)
    pub rate_limit: u32,
    /// Maximum retries for failed requests
    pub max_retries: u32,
    /// Retry delay in milliseconds
    pub retry_delay_ms: u64,
    /// Enable request caching
    pub enable_caching: bool,
    /// Cache TTL in seconds
    pub cache_ttl_seconds: u64,
}

impl DatabentoHistoricalConfig {
    pub fn production() -> Self {
        let endpoints =
            config::DatabentoEndpoints::from_env(config::DataProviderEnvironment::Production);
        Self {
            base_url: endpoints.historical_base_url,
            timeout_seconds: 30,
            rate_limit: 10,
            max_retries: 3,
            retry_delay_ms: 1000,
            enable_caching: true,
            cache_ttl_seconds: 300, // 5 minutes
        }
    }

    pub fn testing() -> Self {
        Self {
            base_url: "https://hist-test.databento.com".to_string(),
            timeout_seconds: 60,
            rate_limit: 5,
            max_retries: 2,
            retry_delay_ms: 2000,
            enable_caching: false,
            cache_ttl_seconds: 60,
        }
    }
}

/// Performance tuning configuration
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerformanceConfig {
    /// Ring buffer size for message processing
    pub ring_buffer_size: usize,
    /// Batch size for processing messages
    pub batch_size: usize,
    /// Maximum memory usage before backpressure (bytes)
    pub max_memory_usage: usize,
    /// Enable SIMD optimizations
    pub enable_simd: bool,
    /// Enable zero-copy operations
    pub enable_zero_copy: bool,
    /// CPU affinity for processing threads
    pub cpu_affinity: Option<Vec<usize>>,
    /// Thread pool size
    pub thread_pool_size: Option<usize>,
}

impl PerformanceConfig {
    pub fn high_frequency() -> Self {
        Self {
            ring_buffer_size: 0x0001_0000, // 64K messages
            batch_size: 2000,
            max_memory_usage: 512 * 1024 * 1024, // 512MB
            enable_simd: true,
            enable_zero_copy: true,
            cpu_affinity: Some(vec![2, 3, 4, 5]), // Dedicated cores for processing
            thread_pool_size: Some(num_cpus::get()),
        }
    }

    pub fn development() -> Self {
        Self {
            ring_buffer_size: 8192, // 8K messages
            batch_size: 100,
            max_memory_usage: 64 * 1024 * 1024, // 64MB
            enable_simd: false,
            enable_zero_copy: false,
            cpu_affinity: None,
            thread_pool_size: None,
        }
    }
}

/// Monitoring and alerting configuration
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MonitoringConfig {
    /// Enable detailed performance metrics
    pub enable_detailed_metrics: bool,
    /// Metrics reporting interval in seconds
    pub metrics_interval_s: u64,
    /// Enable health checks
    pub enable_health_checks: bool,
    /// Health check interval in seconds
    pub health_check_interval_s: u64,
    /// Enable alerting on performance degradation
    pub enable_alerting: bool,
    /// Alert thresholds
    pub alert_thresholds: AlertThresholds,
}

impl MonitoringConfig {
    pub fn production() -> Self {
        Self {
            enable_detailed_metrics: true,
            metrics_interval_s: 10,
            enable_health_checks: true,
            health_check_interval_s: 30,
            enable_alerting: true,
            alert_thresholds: AlertThresholds::production(),
        }
    }

    pub fn development() -> Self {
        Self {
            enable_detailed_metrics: false,
            metrics_interval_s: 60,
            enable_health_checks: false,
            health_check_interval_s: 300,
            enable_alerting: false,
            alert_thresholds: AlertThresholds::development(),
        }
    }
}

/// Alert threshold configuration
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AlertThresholds {
    /// Maximum acceptable latency in nanoseconds
    pub max_latency_ns: u64,
    /// Maximum acceptable error rate (0.0 - 1.0)
    pub max_error_rate: f64,
    /// Minimum acceptable connection stability (0.0 - 1.0)
    pub min_connection_stability: f64,
    /// Maximum acceptable memory usage in bytes
    pub max_memory_usage: usize,
}

impl AlertThresholds {
    pub fn production() -> Self {
        Self {
            max_latency_ns: 5_000,                // 5μs
            max_error_rate: 0.001,                // 0.1%
            min_connection_stability: 0.995,      // 99.5%
            max_memory_usage: 1024 * 1024 * 1024, // 1GB
        }
    }

    pub fn development() -> Self {
        Self {
            max_latency_ns: 100_000,             // 100μs
            max_error_rate: 0.01,                // 1%
            min_connection_stability: 0.90,      // 90%
            max_memory_usage: 512 * 1024 * 1024, // 512MB
        }
    }
}

/// `Databento` symbol representation
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct DatabentoSymbol {
    /// Raw symbol string
    pub raw: String,
    /// Normalized symbol
    pub normalized: String,
    /// Instrument ID
    pub instrument_id: u32,
    /// Symbol type
    pub stype: DatabentoSType,
}

impl From<&str> for DatabentoSymbol {
    fn from(symbol: &str) -> Self {
        Self {
            raw: symbol.to_string(),
            normalized: symbol.to_uppercase(),
            instrument_id: 0, // Would be populated from mapping
            stype: DatabentoSType::RawSymbol,
        }
    }
}

impl From<DatabentoSymbol> for Symbol {
    fn from(databento_symbol: DatabentoSymbol) -> Self {
        Symbol::from(databento_symbol.normalized)
    }
}

/// `Databento` instrument information
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DatabentoInstrument {
    /// Instrument ID
    pub id: u32,
    /// Symbol mapping
    pub symbol: DatabentoSymbol,
    /// Publisher ID
    pub publisher_id: u16,
    /// Dataset
    pub dataset: DatabentoDataset,
    /// Price scaling factor
    pub price_scale: i32,
    /// Size scaling factor
    pub size_scale: i32,
    /// Trading sessions
    pub sessions: Vec<TradingSession>,
}

/// Trading session information
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TradingSession {
    /// Session start time
    pub start: DateTime<Utc>,
    /// Session end time
    pub end: DateTime<Utc>,
    /// Session type (regular, extended, etc.)
    pub session_type: SessionType,
}

/// Session type enumeration
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum SessionType {
    Regular,
    PreMarket,
    PostMarket,
    Extended,
}

/// `Databento` publisher information
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DatabentoPublisher {
    /// Publisher ID
    pub id: u16,
    /// Publisher name
    pub name: String,
    /// Supported datasets
    pub datasets: Vec<DatabentoDataset>,
    /// Data latency characteristics
    pub latency_profile: LatencyProfile,
}

/// Publisher latency profile
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LatencyProfile {
    /// Typical latency in microseconds
    pub typical_latency_us: u64,
    /// 99th percentile latency in microseconds
    pub p99_latency_us: u64,
    /// Data freshness guarantee
    pub freshness_guarantee_ms: u64,
}

/// `Databento` dataset enumeration
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum DatabentoDataset {
    /// NASDAQ Basic
    #[serde(rename = "XNAS.ITCH")]
    NasdaqBasic,
    /// NYSE Trades and Quotes
    #[serde(rename = "XNYS.ITCH")]
    NYSEBasic,
    /// IEX DEEP
    #[serde(rename = "XIEX.TOPS")]
    IEXDeep,
    /// CBOE BZX
    #[serde(rename = "BATS.PITCH")]
    CBOEBZX,
    /// CME Group
    #[serde(rename = "CME.MDP3")]
    CMEGroup,
    /// ICE Futures
    #[serde(rename = "ICE.IMPACT")]
    ICEFutures,
}

impl fmt::Display for DatabentoDataset {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::NasdaqBasic => write!(f, "XNAS.ITCH"),
            Self::NYSEBasic => write!(f, "XNYS.ITCH"),
            Self::IEXDeep => write!(f, "XIEX.TOPS"),
            Self::CBOEBZX => write!(f, "BATS.PITCH"),
            Self::CMEGroup => write!(f, "CME.MDP3"),
            Self::ICEFutures => write!(f, "ICE.IMPACT"),
        }
    }
}

/// `Databento` schema enumeration
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum DatabentoSchema {
    /// Trade data
    #[serde(rename = "trades")]
    Trades,
    /// Top of book quotes
    #[serde(rename = "tbbo")]
    Tbbo,
    /// Market by order data (Level 3)
    #[serde(rename = "mbo")]
    Mbo,
    /// Market by price data (Level 2)
    #[serde(rename = "mbp-1")]
    Mbp1,
    /// Market by price with 10 levels
    #[serde(rename = "mbp-10")]
    Mbp10,
    /// OHLCV bars - 1 second
    #[serde(rename = "ohlcv-1s")]
    Ohlcv1S,
    /// OHLCV bars - 1 minute
    #[serde(rename = "ohlcv-1m")]
    Ohlcv1M,
    /// OHLCV bars - 1 hour
    #[serde(rename = "ohlcv-1h")]
    Ohlcv1H,
    /// OHLCV bars - 1 day
    #[serde(rename = "ohlcv-1d")]
    Ohlcv1D,
    /// Statistics
    #[serde(rename = "statistics")]
    Statistics,
}

impl fmt::Display for DatabentoSchema {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::Trades => write!(f, "trades"),
            Self::Tbbo => write!(f, "tbbo"),
            Self::Mbo => write!(f, "mbo"),
            Self::Mbp1 => write!(f, "mbp-1"),
            Self::Mbp10 => write!(f, "mbp-10"),
            Self::Ohlcv1S => write!(f, "ohlcv-1s"),
            Self::Ohlcv1M => write!(f, "ohlcv-1m"),
            Self::Ohlcv1H => write!(f, "ohlcv-1h"),
            Self::Ohlcv1D => write!(f, "ohlcv-1d"),
            Self::Statistics => write!(f, "statistics"),
        }
    }
}

/// `Databento` symbol type enumeration
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum DatabentoSType {
    /// Raw symbol
    #[serde(rename = "raw_symbol")]
    RawSymbol,
    /// Instrument ID
    #[serde(rename = "instrument_id")]
    InstrumentId,
    /// Parent symbol
    #[serde(rename = "parent")]
    Parent,
    /// Continuous contract
    #[serde(rename = "continuous")]
    Continuous,
}

/// WebSocket message types for `Databento` protocol
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum DatabentoMessage {
    /// Authentication request
    Auth(AuthenticationRequest),
    /// Subscription request
    Subscribe(SubscriptionRequest),
    /// Unsubscribe request
    Unsubscribe(SubscriptionRequest),
    /// Heartbeat message
    Heartbeat(HeartbeatMessage),
    /// Status message
    Status(StatusMessage),
    /// Error message
    Error(ErrorMessage),
    /// Data message (binary DBN)
    Data(Vec<u8>),
}

/// Authentication request message
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthenticationRequest {
    /// API key
    pub key: String,
    /// Optional session ID for resumption
    pub session_id: Option<String>,
}

/// Subscription request message
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SubscriptionRequest {
    /// Dataset to subscribe to
    pub dataset: DatabentoDataset,
    /// Schema type
    pub schema: DatabentoSchema,
    /// Symbols to subscribe to
    pub symbols: Vec<String>,
    /// Symbol type
    pub stype_in: DatabentoSType,
    /// Start timestamp (optional for live data)
    pub start: Option<DateTime<Utc>>,
    /// End timestamp (optional)
    pub end: Option<DateTime<Utc>>,
}

/// Subscription response message
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SubscriptionResponse {
    /// Success status
    pub success: bool,
    /// Session ID
    pub session_id: String,
    /// Number of symbols subscribed
    pub symbols_subscribed: u32,
    /// Error message if failed
    pub error_message: Option<String>,
}

/// Heartbeat message
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HeartbeatMessage {
    /// Timestamp
    pub timestamp: DateTime<Utc>,
    /// Session ID
    pub session_id: String,
}

/// Status message
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StatusMessage {
    /// Status type
    pub status: StatusType,
    /// Human-readable message
    pub message: String,
    /// Timestamp
    pub timestamp: DateTime<Utc>,
}

/// Status type enumeration
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum StatusType {
    Connected,
    Disconnected,
    Subscribed,
    Unsubscribed,
    Warning,
    Info,
}

/// Error message
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ErrorMessage {
    /// Error code
    pub code: u32,
    /// Error message
    pub message: String,
    /// Timestamp
    pub timestamp: DateTime<Utc>,
    /// Additional context
    pub context: Option<serde_json::Value>,
}

/// Connection statistics
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConnectionStats {
    /// Connection uptime
    pub uptime: Duration,
    /// Total messages received
    pub messages_received: u64,
    /// Total bytes received
    pub bytes_received: u64,
    /// Connection attempts
    pub connection_attempts: u32,
    /// Successful connections
    pub successful_connections: u32,
    /// Current connection quality score (0.0 - 1.0)
    pub connection_quality: f64,
}

/// Processing performance statistics
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProcessingStats {
    /// Messages processed per second
    pub messages_per_second: f64,
    /// Average processing latency in nanoseconds
    pub avg_latency_ns: u64,
    /// 95th percentile latency in nanoseconds
    pub p95_latency_ns: u64,
    /// 99th percentile latency in nanoseconds
    pub p99_latency_ns: u64,
    /// Maximum observed latency in nanoseconds
    pub max_latency_ns: u64,
    /// Total messages processed
    pub total_messages: u64,
    /// Processing errors
    pub processing_errors: u32,
}

/// Overall performance metrics
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerformanceMetrics {
    /// Messages per second throughput
    pub messages_per_second: u64,
    /// Average processing latency in nanoseconds
    pub avg_latency_ns: u64,
    /// Error rate (0.0 - 1.0)
    pub error_rate: f64,
    /// System uptime in seconds
    pub uptime_seconds: u64,
    /// Connection stability (0.0 - 1.0)
    pub connection_stability: f64,
}

impl PerformanceMetrics {
    /// Check if performance meets HFT targets
    pub fn meets_hft_targets(&self) -> bool {
        self.avg_latency_ns <= 5_000 &&     // <5μs latency
        self.error_rate <= 0.001 &&         // <0.1% error rate
        self.connection_stability >= 0.999 // >99.9% stability
    }

    /// Get performance score (0.0 - 1.0)
    pub fn performance_score(&self) -> f64 {
        let latency_score = (10_000.0 - self.avg_latency_ns as f64).max(0.0) / 10_000.0;
        let error_score = (0.01 - self.error_rate).max(0.0) / 0.01;
        let stability_score = self.connection_stability;

        (latency_score + error_score + stability_score) / 3.0
    }
}

/// Production configuration presets
pub struct ProductionConfig;

impl ProductionConfig {
    /// Ultra-low latency configuration for market making
    pub fn market_making() -> DatabentoConfig {
        let mut config = DatabentoConfig::production();
        config.performance.ring_buffer_size = 0x0002_0000; // 128K
        config.performance.batch_size = 4000;
        config.performance.cpu_affinity = Some(vec![6, 7, 8, 9]); // Dedicated cores
        config.monitoring.alert_thresholds.max_latency_ns = 2_000; // 2μs
        config
    }

    /// High-throughput configuration for data processing
    pub fn data_processing() -> DatabentoConfig {
        let mut config = DatabentoConfig::production();
        config.performance.ring_buffer_size = 0x0004_0000; // 256K
        config.performance.batch_size = 10000;
        config.performance.max_memory_usage = 2 * 1024 * 1024 * 1024; // 2GB
        config
    }

    /// Balanced configuration for general trading
    pub fn general_trading() -> DatabentoConfig {
        DatabentoConfig::production()
    }
}

/// Testing configuration presets
pub struct TestingConfig;

impl TestingConfig {
    /// Minimal configuration for unit tests
    pub fn unit_test() -> DatabentoConfig {
        let mut config = DatabentoConfig::testing();
        config.performance.ring_buffer_size = 1024;
        config.performance.batch_size = 10;
        config.monitoring.enable_detailed_metrics = false;
        config
    }

    /// Integration test configuration
    pub fn integration_test() -> DatabentoConfig {
        let mut config = DatabentoConfig::testing();
        config.performance.ring_buffer_size = 8192;
        config.performance.batch_size = 100;
        config
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_databento_config_creation() {
        let prod_config = DatabentoConfig::production();
        let test_config = DatabentoConfig::testing();

        assert_eq!(prod_config.environment, DatabentoEnvironment::Production);
        assert_eq!(test_config.environment, DatabentoEnvironment::Testing);

        assert!(prod_config.performance.enable_simd);
        assert!(!test_config.performance.enable_simd);
    }

    #[test]
    fn test_symbol_conversion() {
        let databento_symbol = DatabentoSymbol::from("AAPL");
        assert_eq!(databento_symbol.raw, "AAPL");
        assert_eq!(databento_symbol.normalized, "AAPL");

        let symbol: Symbol = databento_symbol.into();
        assert_eq!(symbol.as_str(), "AAPL");
    }

    #[test]
    fn test_performance_metrics() {
        let metrics = PerformanceMetrics {
            messages_per_second: 100_000,
            avg_latency_ns: 2_000,
            error_rate: 0.0005,
            uptime_seconds: 3600,
            connection_stability: 0.9995,
        };

        assert!(metrics.meets_hft_targets());
        assert!(metrics.performance_score() > 0.9);
    }

    #[test]
    fn test_dataset_display() {
        assert_eq!(DatabentoDataset::NasdaqBasic.to_string(), "XNAS.ITCH");
        assert_eq!(DatabentoDataset::NYSEBasic.to_string(), "XNYS.ITCH");
        assert_eq!(DatabentoDataset::IEXDeep.to_string(), "XIEX.TOPS");
    }

    #[test]
    fn test_schema_display() {
        assert_eq!(DatabentoSchema::Trades.to_string(), "trades");
        assert_eq!(DatabentoSchema::Tbbo.to_string(), "tbbo");
        assert_eq!(DatabentoSchema::Mbo.to_string(), "mbo");
        assert_eq!(DatabentoSchema::Ohlcv1M.to_string(), "ohlcv-1m");
    }

    #[test]
    fn test_production_presets() {
        let market_making = ProductionConfig::market_making();
        let data_processing = ProductionConfig::data_processing();
        let general = ProductionConfig::general_trading();

        assert!(
            market_making.monitoring.alert_thresholds.max_latency_ns
                < general.monitoring.alert_thresholds.max_latency_ns
        );
        assert!(
            data_processing.performance.max_memory_usage > general.performance.max_memory_usage
        );
    }

    #[test]
    fn test_websocket_config_conversion() {
        let config = DatabentoConfig::production();
        let ws_config = config.to_websocket_config();

        assert_eq!(ws_config.api_key, config.api_key);
        assert_eq!(ws_config.endpoint, config.websocket.endpoint);
        assert_eq!(
            ws_config.ring_buffer_size,
            config.performance.ring_buffer_size
        );
    }
}
