use std::sync::OnceLock;

/// Returns a shared, static Tokio runtime for the entire LeanKG engine.
/// This prevents spawning new threads and tokio runtimes repeatedly across synchronous methods.
///
/// WARNING: Never call tokio::runtime::Runtime::new() directly in library code.
/// Creating a runtime is ~100ms overhead (spawns threads, allocates resources).
/// Always use run_blocking() or get_runtime() instead.
pub fn get_runtime() -> &'static tokio::runtime::Runtime {
    static RUNTIME: OnceLock<tokio::runtime::Runtime> = OnceLock::new();
    RUNTIME.get_or_init(|| {
        tokio::runtime::Runtime::new().expect("Failed to initialize static tokio runtime")
    })
}

/// A safe blocking executor that adapts regardless of whether the calling thread is inside a Tokio runtime or not.
pub fn run_blocking<F: std::future::Future>(f: F) -> F::Output {
    if let Ok(_handle) = tokio::runtime::Handle::try_current() {
        // Already inside a tokio runtime - use block_in_place to avoid deadlock
        tokio::task::block_in_place(move || tokio::runtime::Handle::current().block_on(f))
    } else {
        get_runtime().block_on(f)
    }
}
