//! Auth-failure hint for synthesized 401/403 transport errors (WOR-1274).
//!
//! Lives next to the transport rather than inside it so the POST/SSE state
//! machine in `mod.rs` stays focused on wire mechanics; this is the one
//! piece of that error path that is about credentials, not transport.

use reqwest::StatusCode;

/// One-line hint folded into a synthesized 401/403 error. Names the input
/// that fixes the failure and, when the server sent `WWW-Authenticate`,
/// quotes the advertised scheme (and its actionable params) so the caller
/// learns what kind of credential the server wants without a second probe
/// (WOR-1274). Empty for every other status.
pub(super) fn auth_hint(status: StatusCode, resp: &reqwest::Response) -> String {
    let base = match status {
        StatusCode::UNAUTHORIZED => {
            ": the server requires authentication (set `auth.bearer_token_env` or pass `--bearer-token-env`)"
        }
        StatusCode::FORBIDDEN => ": the credential was rejected or lacks permission",
        _ => return String::new(),
    };
    let advertised = resp
        .headers()
        .get(reqwest::header::WWW_AUTHENTICATE)
        .and_then(|v| v.to_str().ok())
        .and_then(crate::network::AuthChallenge::parse);
    let hint = match advertised {
        Some(challenge) => format!("{base}; server advertises {}", challenge.summary()),
        None => base.to_string(),
    };
    // WOR-1268: the synthesized 401/403 message is the one auth failure an
    // operator sees mid-run, so it carries the troubleshooting link inline
    // (the hint is one line inside a JSON-RPC error body, so no newline).
    format!("{hint}; see: {}", crate::error_anchors::AUTH_FAILURE)
}
