// {{ display_name }} MCP server — generated by mcpify. Do not hand-edit.

use axum::http::HeaderMap;

use crate::auth::request_credentials::RequestCredentials;

#[derive(Debug, PartialEq)]
pub enum ExtractError {
    /// The header this auth method needs wasn't present (or was empty).
    Missing,
    /// The auth method's declared location can't be relayed over HTTP
    /// transport at all — only `"header"` locations can (query/cookie
    /// schemes, and OAuth1's `"none"`, are rejected here).
    UnsupportedLocation(String),
}

/// Extracts the credential value for the active auth method's declared
/// location (`AuthManager::header_location`/`header_location_for`) off an
/// incoming HTTP request. The extracted value is relayed verbatim to the
/// facaded API — whatever the caller sent, prefixed or not.
pub fn extract_request_credentials(
    headers: &HeaderMap,
    header_location: &str,
    header_name: &str,
) -> Result<RequestCredentials, ExtractError> {
    if header_location != "header" {
        return Err(ExtractError::UnsupportedLocation(
            header_location.to_string(),
        ));
    }

    let value = headers
        .get(header_name)
        .and_then(|value| value.to_str().ok())
        .filter(|value| !value.is_empty())
        .ok_or(ExtractError::Missing)?;

    Ok(RequestCredentials {
        header_name: header_name.to_string(),
        value: value.to_string(),
    })
}

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

    #[test]
    fn extracts_a_present_header() {
        let mut headers = HeaderMap::new();
        headers.insert("Authorization", "Bearer abc".parse().unwrap());
        let creds = extract_request_credentials(&headers, "header", "Authorization").unwrap();
        assert_eq!(creds.header_name, "Authorization");
        assert_eq!(creds.value, "Bearer abc");
    }

    #[test]
    fn errors_when_the_header_is_absent() {
        let headers = HeaderMap::new();
        assert_eq!(
            extract_request_credentials(&headers, "header", "Authorization"),
            Err(ExtractError::Missing)
        );
    }

    #[test]
    fn errors_when_the_header_is_present_but_empty() {
        let mut headers = HeaderMap::new();
        headers.insert("X-Api-Key", "".parse().unwrap());
        assert_eq!(
            extract_request_credentials(&headers, "header", "X-Api-Key"),
            Err(ExtractError::Missing)
        );
    }

    #[test]
    fn rejects_query_and_cookie_locations() {
        let headers = HeaderMap::new();
        assert_eq!(
            extract_request_credentials(&headers, "query", "api_key"),
            Err(ExtractError::UnsupportedLocation("query".to_string()))
        );
        assert_eq!(
            extract_request_credentials(&headers, "cookie", "session"),
            Err(ExtractError::UnsupportedLocation("cookie".to_string()))
        );
        assert_eq!(
            extract_request_credentials(&headers, "none", ""),
            Err(ExtractError::UnsupportedLocation("none".to_string()))
        );
    }
}
