//! OAuth 2.1 access-token cache and refresh layer.
//!
//! The OAuth login flow is wired end to end: `mcptest login` discovers the
//! authorization server (RFC 9728 + RFC 8414), registers a client (DCR),
//! runs the PKCE authorization-code dance, and caches the token here; the
//! connector then attaches that token to URL servers on `mcptest run`. This
//! module owns the cache plus the *refresh* half. The crate stays
//! transport-free: the actual HTTP exchange against the token endpoint lives
//! behind the [`Refresher`] trait, which the runner crate implements with
//! `reqwest`. Refresh-on-401 during a run is the remaining wiring.
//!
//! See `docs/guides/auth/auth-refresh.md` for the flow, cache layout, and failure
//! modes in prose.

mod civil_date;
pub mod conformance;
mod dcr;
mod device_code;
mod mtls;
mod oauth_pkce;
mod refresh;
mod request_signer;
mod reqwest_refresher;
mod sigv4;
mod sigv4_profile;
mod token;
mod web_bot_auth;
mod web_bot_auth_directory;
mod web_bot_auth_rsa;
mod web_bot_auth_sign;

/// Civil-date helper shared with the doctor mTLS pre-flight so it
/// can render a certificate's expiry date as `YYYY-MM-DD` without a
/// date-formatting dependency.
pub use civil_date::epoch_days_to_ymd;
pub use dcr::{
    register_client, register_with_client, ClientCache, DcrError, RegisterClientRequest,
    RegisterClientResponse,
};
/// OAuth 2.0 device authorization grant (RFC 8628) for `mcptest login
/// --device` (WOR-1286): request a user code, then poll the token
/// endpoint until a human approves on another device.
pub use device_code::{
    device_authorization_with_client, poll_device_token, request_device_authorization,
    DeviceAuthorization, DeviceAuthorizationRequest, DeviceTokenRequest,
};
/// mTLS client-certificate auth scheme.
///
/// Functional: [`mtls::identity`] loads the client cert plus key into a
/// `reqwest::Identity` that the HTTP transports attach at client-build
/// time, and [`mtls::root_certificate`] turns an optional CA bundle into
/// a trusted root. Composes with bearer tokens and static headers.
pub use mtls::{
    build_tls_config, certificate_validity, check_key_file_permissions, identity, root_certificate,
    CertValidity, MtlsConfig,
};
pub use oauth_pkce::{
    client_credentials_with_client, exchange_client_credentials, exchange_code,
    exchange_with_client, random_state, AuthorizationUrl, ClientCredentialsRequest, OAuthError,
    PkceParams, TokenExchangeRequest,
};
pub use refresh::{maybe_refresh, should_refresh_on_response, BoxedRefresher, Refresher};
/// Per-request signing step shared by the HTTP transports. Holds the
/// optional SigV4 and Web Bot Auth configs and computes the headers to
/// attach.
pub use request_signer::RequestSigner;
pub use reqwest_refresher::{ReqwestRefresher, ReqwestRefresherConfig};
/// AWS SigV4 request-signing auth scheme.
///
/// Functional: [`sigv4::sign_request`] signs an outbound request per
/// request, returning `Authorization`, `X-Amz-Date`, and (when present)
/// `X-Amz-Security-Token`.
pub use sigv4::{sign_request as sigv4_sign_request, SigV4Config, SigV4Credentials};
/// AWS named-profile resolution for SigV4. The signer resolves a
/// profile internally; this re-export lets the doctor pre-flight confirm a
/// profile resolves from `~/.aws/credentials` (a local, no-network check)
/// without ever surfacing the resolved secret.
pub use sigv4_profile::check_profile_resolves as resolve_sigv4_profile;
pub use token::{AuthError, Token, TokenCache, TokenLockGuard};
/// Web Bot Auth (RFC 9421 HTTP message signatures) auth scheme (,
/// ).
///
/// Config plus validation. [`web_bot_auth::sign_request`] builds the RFC
/// 9421 signature base over the configured components and attaches
/// `Signature`, `Signature-Input`, and `Signature-Agent` (Ed25519 or
/// RSA-PSS).
pub use web_bot_auth::{
    preflight_signing_key as web_bot_auth_preflight_key, sign_request as web_bot_auth_sign_request,
    SignatureAlgorithm, WebBotAuthConfig,
};
/// Web Bot Auth public-key directory emission. Builds the
/// `.well-known/http-message-signatures-directory` JWK Set for a configured
/// signing key so an operator can publish the bot's PUBLIC key. The private
/// key never leaves the builder.
pub use web_bot_auth_directory::{
    build_directory as web_bot_auth_directory, directory_json_string as web_bot_auth_directory_json,
};

/// Shared lock for tests that mutate the process-global AWS credential-file env
/// vars (`sigv4` and `sigv4_profile`). The default test harness runs tests in
/// parallel, so without serializing them one test's `set_var` races another's
/// `remove_var` and the profile resolves against the wrong (or no) file.
#[cfg(test)]
pub(crate) fn aws_env_lock() -> std::sync::MutexGuard<'static, ()> {
    static M: std::sync::Mutex<()> = std::sync::Mutex::new(());
    M.lock().unwrap_or_else(|e| e.into_inner())
}
