//! # ML Labeling Module for Foxhunt HFT System
//!
//! This module provides high-performance machine learning labeling algorithms
//! optimized for ultra-low latency financial applications. All implementations
//! use `FixedPoint` arithmetic for financial precision and target sub-microsecond
//! performance.
//!
//! ## Core Features
//!
//! - **Triple Barrier Engine**: <80us latency for event labeling
//! - **Meta-Labeling**: Separates direction prediction from confidence/bet sizing
//! - **Fractional Differentiation**: Streaming transforms with <1us latency
//! - **Sample Weighting**: Volatility/return/time-based weighting algorithms
//! - **GPU Acceleration**: Batch processing with CUDA via cudarc integration
//! - **Concurrent Processing**: Lock-free barrier tracking with `DashMap`
//!
//! ## Performance Targets
//!
//! - Triple barrier labeling: <80us per event
//! - Meta-labeling: <50us per prediction
//! - Fractional differentiation: <1us per transform
//! - Sample weighting: <10us per sample
//! - Batch processing: 10K+ labels/second
//!
//! ## Architecture
//!
//! All components use integer arithmetic (cents, nanoseconds, basis points)
//! for financial precision, matching the Python reference implementation
//! patterns from the `HFTTrendfollowing` project.

#![deny(clippy::unwrap_used, clippy::expect_used)]
#![cfg_attr(test, allow(clippy::unwrap_used, clippy::expect_used))]
#![allow(clippy::module_name_repetitions)]
#![allow(clippy::integer_division)]
// Overrides of workspace deny → allow (labeling code uses these patterns)
#![allow(clippy::shadow_reuse, clippy::shadow_same, clippy::shadow_unrelated)]
#![allow(clippy::non_ascii_literal, clippy::str_to_string)]
#![allow(clippy::partial_pub_fields, clippy::multiple_inherent_impl)]
#![allow(clippy::same_name_method, clippy::indexing_slicing)]

// Re-export MLError so internal modules can use `crate::MLError`
pub use ml_core::MLError;

pub mod benchmarks;
pub mod concurrent_tracking;
pub mod fractional_diff;
pub mod gpu_acceleration;

// Meta-labeling engine (legacy interface)
pub mod meta_labeling_engine;

// New meta-labeling module with secondary model
pub mod meta_labeling;

pub mod sample_weights;
pub mod triple_barrier;
pub mod types;

// DO NOT RE-EXPORT - Use explicit imports at usage sites

// DO NOT RE-EXPORT - Benchmarks should be imported explicitly

/// Labeling module constants matching Python reference precision
pub mod constants {
    /// Cents per dollar for `price` precision
    pub const CENTS_PER_DOLLAR: i64 = 100;

    /// Basis points per dollar for return precision
    pub const BASIS_POINTS_PER_DOLLAR: i64 = 10_000;

    /// Nanoseconds per second for time precision
    pub const NANOSECONDS_PER_SECOND: i64 = 1_000_000_000;

    /// Microseconds per second
    pub const MICROSECONDS_PER_SECOND: i64 = 1_000_000;

    /// Maximum latency target for triple barrier labeling (80us)
    pub const MAX_TRIPLE_BARRIER_LATENCY_US: u64 = 80;

    /// Maximum latency target for meta-labeling (50us)
    pub const MAX_META_LABELING_LATENCY_US: u64 = 50;

    /// Maximum latency target for fractional differentiation (1us)
    pub const MAX_FRACTIONAL_DIFF_LATENCY_US: u64 = 1;

    /// Minimum throughput for batch processing (labels/second)
    pub const MIN_BATCH_THROUGHPUT_LPS: u64 = 10_000;
}

/// Utility functions for labeling operations
pub mod utils {
    use super::constants::{CENTS_PER_DOLLAR, BASIS_POINTS_PER_DOLLAR, NANOSECONDS_PER_SECOND};

    /// Convert price to cents
    pub fn price_to_cents(price: f64) -> u64 {
        (price * CENTS_PER_DOLLAR as f64) as u64
    }

    /// Convert cents to price
    pub fn cents_to_price(cents: u64) -> f64 {
        cents as f64 / CENTS_PER_DOLLAR as f64
    }

    /// Convert ratio to basis points
    pub fn ratio_to_bps(ratio: f64) -> i32 {
        (ratio * BASIS_POINTS_PER_DOLLAR as f64) as i32
    }

    /// Convert basis points to ratio
    pub fn bps_to_ratio(bps: i32) -> f64 {
        bps as f64 / BASIS_POINTS_PER_DOLLAR as f64
    }

    /// Convert timestamp to nanoseconds
    pub fn timestamp_to_ns(timestamp: f64) -> u64 {
        (timestamp * NANOSECONDS_PER_SECOND as f64) as u64
    }

    /// Convert nanoseconds to timestamp
    pub fn ns_to_timestamp(ns: u64) -> f64 {
        ns as f64 / NANOSECONDS_PER_SECOND as f64
    }
}

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

    #[test]
    fn test_price_conversions() {
        let price = 123.45;
        let cents = utils::price_to_cents(price);
        let converted_back = utils::cents_to_price(cents);

        assert_eq!(cents, 12345);
        assert!((converted_back - price).abs() < 1e-10);
    }

    #[test]
    fn test_ratio_conversions() {
        let ratio = 0.0250; // 2.5%
        let bps = utils::ratio_to_bps(ratio);
        let converted_back = utils::bps_to_ratio(bps);

        assert_eq!(bps, 250);
        assert!((converted_back - ratio).abs() < 1e-10);
    }

    #[test]
    fn test_timestamp_conversions() {
        let timestamp = 1692000000.123456789; // Example timestamp with nanosecond precision
        let ns = utils::timestamp_to_ns(timestamp);
        let converted_back = utils::ns_to_timestamp(ns);

        // Should preserve millisecond precision
        assert!((converted_back - timestamp).abs() < 1e-6);
    }
}
