use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;

/// Resolves the current API key for tool HTTP requests.
pub trait ApiKeyProvider: Send + Sync + 'static {
    /// Sync cached read (no refresh). Override point for static providers.
    fn current_api_key(&self) -> Option<String>;

    /// Per-request resolve. `AuthManager` overrides this to drive the
    /// refresh chain; default delegates to the sync method.
    fn current_api_key_async(&self) -> Pin<Box<dyn Future<Output = Option<String>> + Send + '_>> {
        Box::pin(std::future::ready(self.current_api_key()))
    }
}

/// Shared provider used across tool clients.
pub type SharedApiKeyProvider = Arc<dyn ApiKeyProvider>;

/// Resolve the bearer for the next request from the provider.
pub(crate) async fn resolve_bearer(provider: Option<&SharedApiKeyProvider>) -> Option<String> {
    match provider {
        Some(p) => p.current_api_key_async().await,
        None => None,
    }
}

/// Test fixtures shared by tool-client tests.
#[cfg(test)]
pub(crate) mod test_support {
    use super::*;

    struct FixedProvider(String);
    impl ApiKeyProvider for FixedProvider {
        fn current_api_key(&self) -> Option<String> {
            Some(self.0.clone())
        }
    }

    /// A provider that always yields `token` — stands in for the OAuth
    /// refresh chain in client tests.
    pub(crate) fn fixed_provider(token: &str) -> SharedApiKeyProvider {
        Arc::new(FixedProvider(token.to_owned()))
    }
}
