use std::env;
use std::sync::OnceLock;
static AUTH_TOKEN_GETTER: OnceLock<Box<dyn Fn() -> Option<String> + Send + Sync>> = OnceLock::new();
static BASE_URL_GETTER: OnceLock<Box<dyn Fn() -> String + Send + Sync>> = OnceLock::new();
pub fn register_oauth_token_getter(getter: impl Fn() -> Option<String> + Send + Sync + 'static) {
let _ = AUTH_TOKEN_GETTER.set(Box::new(getter));
}
pub fn register_oauth_base_url_getter(getter: impl Fn() -> String + Send + Sync + 'static) {
let _ = BASE_URL_GETTER.set(Box::new(getter));
}
fn get_oauth_config_base_url() -> String {
BASE_URL_GETTER
.get()
.map(|getter| getter())
.unwrap_or_else(|| "https://api.anthropic.com".to_string())
}
fn get_oauth_access_token() -> Option<String> {
AUTH_TOKEN_GETTER.get().and_then(|getter| getter())
}
pub fn get_bridge_token_override() -> Option<String> {
if is_ant_user() {
env::var("CLAUDE_BRIDGE_OAUTH_TOKEN").ok()
} else {
None
}
}
pub fn get_bridge_base_url_override() -> Option<String> {
if is_ant_user() {
env::var("CLAUDE_BRIDGE_BASE_URL").ok()
} else {
None
}
}
fn is_ant_user() -> bool {
env::var("USER_TYPE").map(|v| v == "ant").unwrap_or(false)
}
pub fn get_bridge_access_token() -> Option<String> {
get_bridge_token_override().or_else(get_oauth_access_token)
}
pub fn get_bridge_base_url() -> String {
get_bridge_base_url_override().unwrap_or_else(get_oauth_config_base_url)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_bridge_access_token_no_override() {
let token = get_bridge_access_token();
let _ = token;
}
#[test]
fn test_bridge_base_url_default() {
let url = get_bridge_base_url();
assert!(!url.is_empty());
}
}