// Proxy middleware — API key redaction in error traces
use axum::http::HeaderMap;
use tracing::warn;

/// Redact any Bearer tokens or API keys from a string.
/// Used in panic handlers and error logging to prevent key leakage.
pub fn redact_sensitive(input: &str) -> String {
    let patterns = [
        // OpenAI keys
        (r"sk-[a-zA-Z0-9_-]{20,}", "[REDACTED_API_KEY]"),
        // Anthropic keys
        (r"sk-ant-[a-zA-Z0-9_-]{20,}", "[REDACTED_API_KEY]"),
        // Bearer tokens
        (r"Bearer\s+[a-zA-Z0-9_.-]+", "Bearer [REDACTED]"),
    ];

    let mut result = input.to_string();
    for (pattern, replacement) in &patterns {
        if let Ok(re) = regex::Regex::new(pattern) {
            result = re.replace_all(&result, *replacement).to_string();
        }
    }
    result
}

/// Extract API key from Authorization header, returning redacted version for logging
pub fn extract_api_key(headers: &HeaderMap) -> Option<String> {
    headers
        .get("authorization")
        .and_then(|v| v.to_str().ok())
        .and_then(|v| v.strip_prefix("Bearer "))
        .map(|s| s.to_string())
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn redacts_openai_key() {
        let input = "Error with key sk-proj-abc123xyz456def789ghi";
        let result = redact_sensitive(input);
        assert!(!result.contains("sk-proj-abc123xyz456def789ghi"));
        assert!(result.contains("[REDACTED_API_KEY]"));
    }

    #[test]
    fn redacts_bearer_token() {
        let input = "Authorization: Bearer sk-live-abc123xyz";
        let result = redact_sensitive(input);
        assert!(!result.contains("sk-live-abc123xyz"));
        assert!(result.contains("[REDACTED]"));
    }

    #[test]
    fn does_not_redact_normal_text() {
        let input = "Hello world, this is a normal log message";
        let result = redact_sensitive(input);
        assert_eq!(result, input);
    }
}
