use std::io;

use ringline_h2::H2Error;

/// Errors produced by the HTTP client.
#[derive(Debug, thiserror::Error)]
pub enum HttpError {
    /// The connection was closed unexpectedly.
    #[error("connection closed")]
    ConnectionClosed,

    /// HTTP/2 framing error.
    #[error("h2 error: {0}")]
    H2(#[from] H2Error),

    /// I/O error.
    #[error("io error: {0}")]
    Io(#[from] io::Error),

    /// Invalid URL or path.
    #[error("invalid url: {0}")]
    InvalidUrl(String),

    /// Response parsing error.
    #[error("parse error")]
    Parse,

    /// Parsed message is syntactically valid but rejected on semantic
    /// grounds — e.g., conflicting `Transfer-Encoding` + `Content-Length`
    /// (RFC 9112 §6.3 request smuggling defense), multiple `Content-Length`
    /// headers with different values, header values containing CR/LF/NUL,
    /// or unsupported transfer codings.
    #[error("invalid message: {0}")]
    InvalidMessage(String),

    /// A configured resource cap (max header section, max body, max chunk,
    /// max trailer, max decompressed size) was exceeded.
    #[error("max size exceeded: {0}")]
    MaxSizeExceeded(String),

    /// Request timed out.
    #[error("timeout")]
    Timeout,

    /// H2 flow control blocked and could not be resolved.
    #[error("flow control error")]
    FlowControl,

    /// All connections in a pool failed.
    #[error("all connections failed")]
    AllConnectionsFailed,

    /// Protocol error (unexpected event, bad state).
    #[error("protocol error: {0}")]
    Protocol(String),

    /// Decompression error.
    #[error("decompression error: {0}")]
    Decompress(String),
}
