/// Hurst Exponent Division by Zero Validation Test
///
/// This test validates the fixes for Hurst exponent division by zero errors:
/// 1. ml/src/regime/trending.rs:394 - Window size validation (n > 1.5)
/// 2. ml/src/features/price_features.rs - Same validation in feature extraction
///
/// Expected behavior:
/// - 1-bar window: Returns 0.5 (random walk assumption)
/// - 2-bar window: Returns 0.5 (n=1.0, below threshold)
/// - Small windows (<10): Returns 0.5 (fallback)
/// - Valid windows (>=10): Calculates Hurst exponent normally

use std::collections::VecDeque;

#[path = "ml/src/features/price_features.rs"]
mod price_features;
use price_features::{OHLCVBar, PriceFeatureExtractor};

fn create_test_bar(close: f64) -> OHLCVBar {
    OHLCVBar {
        timestamp: chrono::Utc::now(),
        open: close,
        high: close * 1.01,
        low: close * 0.99,
        close,
        volume: 1000.0,
    }
}

fn main() {
    println!("=== Hurst Exponent Division by Zero Validation ===\n");

    // Test 1: 1-bar window (edge case)
    let mut bars_1 = VecDeque::new();
    bars_1.push_back(create_test_bar(100.0));
    let hurst_1 = PriceFeatureExtractor::compute_hurst_exponent(&bars_1, 1);
    println!("✓ Test 1: 1-bar window");
    println!("  Hurst exponent: {:.4}", hurst_1);
    println!("  Expected: 0.5000 (random walk)");
    assert_eq!(hurst_1, 0.5, "1-bar window should return 0.5");
    println!("  PASS: No division by zero\n");

    // Test 2: 2-bar window (n=1.0 after returns, below 1.5 threshold)
    let mut bars_2 = VecDeque::new();
    bars_2.push_back(create_test_bar(100.0));
    bars_2.push_back(create_test_bar(101.0));
    let hurst_2 = PriceFeatureExtractor::compute_hurst_exponent(&bars_2, 2);
    println!("✓ Test 2: 2-bar window");
    println!("  Hurst exponent: {:.4}", hurst_2);
    println!("  Expected: 0.5000 (n=1.0, below threshold)");
    assert_eq!(hurst_2, 0.5, "2-bar window should return 0.5");
    println!("  PASS: No division by zero\n");

    // Test 3: Small window (<10 bars)
    let mut bars_small = VecDeque::new();
    for i in 0..5 {
        bars_small.push_back(create_test_bar(100.0 + i as f64));
    }
    let hurst_small = PriceFeatureExtractor::compute_hurst_exponent(&bars_small, 5);
    println!("✓ Test 3: 5-bar window (insufficient data)");
    println!("  Hurst exponent: {:.4}", hurst_small);
    println!("  Expected: 0.5000 (fallback for <10 bars)");
    assert_eq!(hurst_small, 0.5, "Small window should return 0.5");
    println!("  PASS: Fallback to random walk\n");

    // Test 4: Valid window (30 bars, trending)
    let mut bars_valid = VecDeque::new();
    for i in 0..30 {
        bars_valid.push_back(create_test_bar(100.0 + (i as f64 * 0.5)));
    }
    let hurst_valid = PriceFeatureExtractor::compute_hurst_exponent(&bars_valid, 20);
    println!("✓ Test 4: 30-bar trending series");
    println!("  Hurst exponent: {:.4}", hurst_valid);
    println!("  Expected: 0.5-1.0 (valid calculation)");
    assert!(hurst_valid >= 0.0 && hurst_valid <= 1.0, "Valid Hurst should be in [0, 1]");
    assert!(hurst_valid.is_finite(), "Valid Hurst should be finite");
    println!("  PASS: Valid Hurst calculation (no NaN/Inf)\n");

    // Test 5: Constant prices (zero volatility)
    let mut bars_const = VecDeque::new();
    for _ in 0..30 {
        bars_const.push_back(create_test_bar(100.0));
    }
    let hurst_const = PriceFeatureExtractor::compute_hurst_exponent(&bars_const, 20);
    println!("✓ Test 5: 30-bar constant series (zero volatility)");
    println!("  Hurst exponent: {:.4}", hurst_const);
    println!("  Expected: 0.5000 (zero volatility fallback)");
    assert_eq!(hurst_const, 0.5, "Zero volatility should return 0.5");
    println!("  PASS: Zero volatility handled\n");

    // Test 6: Feature extraction with edge cases
    let mut bars_feature = VecDeque::new();
    bars_feature.push_back(create_test_bar(100.0));
    let features = PriceFeatureExtractor::extract_all(&bars_feature);
    println!("✓ Test 6: Feature extraction with 1-bar window");
    println!("  Feature 13 (Hurst): {:.4}", features[13]);
    println!("  Feature 14 (Fractal): {:.4}", features[14]);
    assert!(features[13].is_finite(), "Hurst feature should be finite");
    assert!(features[14].is_finite(), "Fractal dimension should be finite");
    println!("  PASS: No NaN/Inf in feature extraction\n");

    println!("=== All Tests Passed ===");
    println!("✓ Window size validation working (n > 1.5)");
    println!("✓ 1-bar window returns 0.5 (no division by zero)");
    println!("✓ Zero volatility returns 0.5 (no NaN)");
    println!("✓ Valid windows calculate Hurst correctly");
    println!("✓ No NaN or Inf values in feature extraction");
}
