// Suppress warning from PyO3 macro expansion (fixed in newer PyO3 versions)
#![allow(non_local_definitions)]

//! RaptorBT - High-performance Rust backtesting engine.
//!
//! This crate provides a complete backtesting solution with:
//! - Technical indicators (SMA, EMA, RSI, MACD, etc.)
//! - Portfolio simulation engine
//! - Multiple strategy types (single, basket, options, pairs, multi)
//! - Stop-loss and take-profit mechanisms
//! - Streaming metrics calculation

use pyo3::prelude::*;

pub mod core;
pub mod execution;
pub mod indicators;
pub mod metrics;
pub mod portfolio;
pub mod python;
pub mod signals;
pub mod stops;
pub mod strategies;

/// Python module entry point
#[pymodule]
fn _raptorbt(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
    // Register config classes
    m.add_class::<python::bindings::PyBacktestConfig>()?;
    m.add_class::<python::bindings::PyInstrumentConfig>()?;
    m.add_class::<python::bindings::PyStopConfig>()?;
    m.add_class::<python::bindings::PyTargetConfig>()?;

    // Register result classes
    m.add_class::<python::bindings::PyBacktestResult>()?;
    m.add_class::<python::bindings::PyBacktestMetrics>()?;
    m.add_class::<python::bindings::PyTrade>()?;

    // Register backtest functions
    m.add_function(wrap_pyfunction!(python::bindings::run_single_backtest, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::run_basket_backtest, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::run_options_backtest, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::run_pairs_backtest, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::run_multi_backtest, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::run_spread_backtest, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::run_tick_backtest, m)?)?;

    // Register batch spread backtest
    m.add_class::<python::bindings::PyBatchSpreadItem>()?;
    m.add_function(wrap_pyfunction!(python::bindings::batch_spread_backtest, m)?)?;

    // Register Monte Carlo simulation
    m.add_function(wrap_pyfunction!(python::bindings::simulate_portfolio_mc, m)?)?;

    // Register tick signal functions
    m.add_function(wrap_pyfunction!(python::bindings::compute_tick_entry_signals, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::compute_tick_exit_signals, m)?)?;

    // Register tick feature functions
    m.add_function(wrap_pyfunction!(python::bindings::tick_spread_pct, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::buy_sell_imbalance_delta, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::return_window, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::realized_vol_rolling, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::oi_position_pct, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::tick_velocity, m)?)?;

    // Register indicator functions
    m.add_function(wrap_pyfunction!(python::bindings::sma, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::ema, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::rsi, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::macd, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::stochastic, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::atr, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::bollinger_bands, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::adx, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::vwap, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::supertrend, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::rolling_min, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::rolling_max, m)?)?;

    // Extended indicators (via ferro_ta_core)
    m.add_function(wrap_pyfunction!(python::bindings::cci, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::willr, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::sar, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::plus_di, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::minus_di, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::adx_all, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::adxr, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::roc, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::mfi, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::wma, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::dema, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::tema, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::kama, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::stochrsi, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::aroon, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::trix, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::natr, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::trange, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::stddev, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::var, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::linearreg, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::linearreg_slope, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::linearreg_intercept, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::linearreg_angle, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::tsf, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::beta, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::correl, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::ad, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::adosc, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::obv, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::mom, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::ppo, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::cmo, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::aroonosc, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::bop, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::ultosc, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::typprice, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::medprice, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::avgprice, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::wclprice, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::midpoint, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::midprice, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::t3, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::trima, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::apo, m)?)?;

    // P0 batch — Extended (donchian / hull_ma / ichimoku / pivot_points / etc.)
    m.add_function(wrap_pyfunction!(python::bindings::vwma, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::donchian, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::choppiness_index, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::hull_ma, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::chandelier_exit, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::ichimoku, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::pivot_points, m)?)?;

    // P0 batch — Hilbert Transform (cycle)
    m.add_function(wrap_pyfunction!(python::bindings::ht_trendline, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::ht_dcperiod, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::ht_dcphase, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::ht_phasor, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::ht_sine, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::ht_trendmode, m)?)?;

    // P0 batch — Market regime detection
    m.add_function(wrap_pyfunction!(python::bindings::regime_adx, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::regime_combined, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::detect_breaks_cusum, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::rolling_variance_break, m)?)?;

    // P0 batch — Portfolio / cross-series tools
    m.add_function(wrap_pyfunction!(python::bindings::rolling_beta, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::drawdown_series, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::zscore_series, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::relative_strength, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::spread, m)?)?;
    m.add_function(wrap_pyfunction!(python::bindings::ratio, m)?)?;

    Ok(())
}