// src/utils/rdconfig.rs
use redis::aio::ConnectionManager;
use tokio::sync::OnceCell;
use crate::config::get_redis_url;

/// Process-wide shared Redis connection.
static SHARED_CONNECTION: OnceCell<ConnectionManager> = OnceCell::const_new();

/// Return a shared, multiplexed Redis connection.
///
/// The `ConnectionManager` is initialized once and cached; subsequent calls
/// return a cheap clone that shares a single underlying connection and
/// transparently reconnects if it drops. This replaces the previous behavior
/// of opening a brand-new client + connection on every call (which, in the
/// worker loop, meant a fresh TCP connect and handshake several times a second).
pub async fn get_redis_connection() -> redis::RedisResult<ConnectionManager> {
    let conn = SHARED_CONNECTION
        .get_or_try_init(|| async {
            let client = redis::Client::open(get_redis_url())?;
            ConnectionManager::new(client).await
        })
        .await?;
    Ok(conn.clone())
}

/// Open a fresh, dedicated Redis connection (not the shared one).
///
/// Blocking commands such as BLMOVE/BLPOP must not run on the shared
/// connection, since a command that parks on the server would stall every
/// other operation multiplexed over it. Each worker owns one of these for
/// its blocking fetch loop.
pub async fn get_dedicated_connection() -> redis::RedisResult<redis::aio::MultiplexedConnection> {
    let client = redis::Client::open(get_redis_url())?;
    client.get_multiplexed_async_connection().await
}
