"""Rust acceleration wrapper — falls back to Python if Rust extension not available.

The Rust module `cpz_risk_rs` provides:
- monte_carlo_var: ~10x faster Monte Carlo VaR (parallel via rayon)
- covariance_matrix: ~5x faster covariance computation
- risk_parity_weights: ~3x faster risk parity optimization

Build with: cd rust && maturin develop --release
"""

from __future__ import annotations

from typing import Dict, List, Optional

try:
    import cpz_risk_rs

    RUST_AVAILABLE = True
except ImportError:
    RUST_AVAILABLE = False


def has_rust() -> bool:
    """Check if Rust acceleration is available."""
    return RUST_AVAILABLE


def fast_monte_carlo_var(
    daily_returns: List[float],
    num_simulations: int = 100000,
    horizon_days: int = 1,
    seed: Optional[int] = 42,
) -> Optional[Dict]:
    """Run Monte Carlo VaR using Rust (if available).

    Returns dict with var_95, var_99, expected_shortfall_95/99, etc.
    Returns None if Rust is not available (caller should use Python fallback).
    """
    if not RUST_AVAILABLE:
        return None
    return cpz_risk_rs.monte_carlo_var(daily_returns, num_simulations, horizon_days, seed)


def fast_covariance_matrix(
    returns_flat: List[float],
    n_assets: int,
    n_days: int,
) -> Optional[List[float]]:
    """Compute annualized covariance matrix using Rust.

    Returns flat covariance matrix (n_assets x n_assets) or None if Rust unavailable.
    """
    if not RUST_AVAILABLE:
        return None
    return cpz_risk_rs.covariance_matrix(returns_flat, n_assets, n_days)


def fast_risk_parity(
    cov_flat: List[float],
    n_assets: int,
    max_iter: int = 500,
) -> Optional[List[float]]:
    """Compute risk parity weights using Rust.

    Returns optimal weights or None if Rust unavailable.
    """
    if not RUST_AVAILABLE:
        return None
    return cpz_risk_rs.risk_parity_weights(cov_flat, n_assets, max_iter)
