// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

use iggy::prelude::{
    AutoLogin as RustAutoLogin, Credentials as RustCredentials,
    HttpClientConfig as RustHttpClientConfig, HttpClientConfigBuilder,
    QuicClientConfig as RustQuicClientConfig, QuicClientConfigBuilder,
    QuicClientReconnectionConfig as RustQuicClientReconnectionConfig,
    TcpClientConfig as RustTcpClientConfig, TcpClientConfigBuilder,
    TcpClientReconnectionConfig as RustTcpClientReconnectionConfig,
    WebSocketClientConfig as RustWebSocketClientConfig, WebSocketClientConfigBuilder,
    WebSocketClientReconnectionConfig as RustWebSocketClientReconnectionConfig,
    WebSocketConfig as RustWebSocketFramingConfig,
};
use pyo3::exceptions::PyValueError;
use pyo3::prelude::*;
use pyo3::types::PyDelta;
use pyo3_stub_gen::derive::{gen_stub_pyclass, gen_stub_pymethods};
use pyo3_stub_gen::impl_stub_type;
use secrecy::SecretString;
use std::fmt::Display;
use std::net::SocketAddr;
use std::sync::Arc;

use crate::duration::{
    duration_repr, iggy_duration_to_py_delta, millis_repr, millis_to_py_delta,
    py_delta_to_iggy_duration, py_delta_to_millis, reject_zero,
};

/// The credentials replayed by the client every time it (re)connects.
///
/// `IggyClient` only recovers a lost session when it has credentials to replay,
/// so a long-running consumer should pass one of the enabled variants.
#[gen_stub_pyclass]
#[pyclass(from_py_object)]
#[derive(Clone)]
pub struct AutoLogin {
    pub(crate) inner: RustAutoLogin,
}

#[gen_stub_pymethods]
#[pymethods]
impl AutoLogin {
    /// No automatic login. `login_user()` must be called by hand after every connect.
    #[staticmethod]
    fn disabled() -> Self {
        Self {
            inner: RustAutoLogin::Disabled,
        }
    }

    /// Log in with the given username and password on every connect.
    #[staticmethod]
    fn username_password(username: String, password: String) -> Self {
        Self {
            inner: RustAutoLogin::Enabled(RustCredentials::UsernamePassword(
                username,
                SecretString::from(password),
            )),
        }
    }

    /// Log in with the given personal access token on every connect.
    #[staticmethod]
    fn personal_access_token(token: String) -> Self {
        Self {
            inner: RustAutoLogin::Enabled(RustCredentials::PersonalAccessToken(
                SecretString::from(token),
            )),
        }
    }

    /// Whether automatic login is enabled.
    #[getter]
    fn enabled(&self) -> bool {
        matches!(self.inner, RustAutoLogin::Enabled(_))
    }

    /// The username to log in with, or `None` for the disabled and token variants.
    #[gen_stub(override_return_type(type_repr = "builtins.str | None"))]
    #[getter]
    fn username(&self) -> Option<String> {
        match &self.inner {
            RustAutoLogin::Enabled(RustCredentials::UsernamePassword(username, _)) => {
                Some(username.clone())
            }
            _ => None,
        }
    }

    fn __repr__(&self) -> String {
        match &self.inner {
            RustAutoLogin::Disabled => "AutoLogin.disabled()".to_owned(),
            RustAutoLogin::Enabled(RustCredentials::UsernamePassword(username, _)) => {
                format!("AutoLogin.username_password({username:?}, ...)")
            }
            RustAutoLogin::Enabled(RustCredentials::PersonalAccessToken(_)) => {
                "AutoLogin.personal_access_token(...)".to_owned()
            }
        }
    }
}

/// How the TCP client reconnects after the connection to the server is lost.
#[gen_stub_pyclass]
#[pyclass(from_py_object)]
#[derive(Clone)]
pub struct TcpReconnectionConfig {
    pub(crate) inner: RustTcpClientReconnectionConfig,
}

#[gen_stub_pymethods]
#[pymethods]
impl TcpReconnectionConfig {
    /// Constructs a reconnection policy.
    ///
    /// Args:
    ///     enabled: Whether to reconnect at all. Defaults to enabled.
    ///     max_retries: Passes over the known endpoints after the first, or
    ///         `None` for unlimited; `0` still makes that first pass. One pass
    ///         tries the endpoint the client is on, the address it was
    ///         configured with, and every node the roster named, so this counts
    ///         passes rather than dials. Defaults
    ///         to unlimited, which means a call awaited while the server is
    ///         down never returns: `connect()`, `send_messages()` and
    ///         `poll_messages()` all wait inside the retry loop. Set a finite
    ///         number for request/reply style usage, so a call fails instead.
    ///     interval: Delay between passes. Defaults to 1 second. The first pass
    ///         runs at once when more than one endpoint is known.
    ///     reestablish_after: Cooldown before redialing the endpoint of the last
    ///         successful connection, measured from when it was established, so
    ///         a session that outlived the interval is redialed at once. Owed to
    ///         that endpoint alone. Defaults to 5 seconds.
    ///
    /// Raises:
    ///     ValueError: If a duration is negative, if `max_retries` is outside the
    ///         range of an unsigned 32-bit integer, or if `interval` is zero.
    ///     OverflowError: If `max_retries` does not fit a signed 64-bit integer,
    ///         raised by the underlying conversion before this constructor runs.
    #[new]
    #[pyo3(signature = (*, enabled=None, max_retries=None, interval=None, reestablish_after=None))]
    fn new(
        #[gen_stub(override_type(type_repr = "builtins.bool | None"))] enabled: Option<bool>,
        #[gen_stub(override_type(type_repr = "builtins.int | None"))] max_retries: Option<i64>,
        #[gen_stub(override_type(type_repr = "datetime.timedelta | None", imports=("datetime")))]
        interval: Option<Py<PyDelta>>,
        #[gen_stub(override_type(type_repr = "datetime.timedelta | None", imports=("datetime")))]
        reestablish_after: Option<Py<PyDelta>>,
    ) -> PyResult<Self> {
        let defaults = RustTcpClientReconnectionConfig::default();
        let enabled = enabled.unwrap_or(defaults.enabled);
        let max_retries = max_retries
            .map(|max_retries| u32_param(max_retries, "max_retries"))
            .transpose()?;
        let interval = interval
            .as_ref()
            .map(py_delta_to_iggy_duration)
            .transpose()?
            .map(|interval| reject_zero(interval, "interval"))
            .transpose()?
            .unwrap_or(defaults.interval);
        Ok(Self {
            inner: RustTcpClientReconnectionConfig {
                enabled,
                max_retries,
                interval,
                reestablish_after: reestablish_after
                    .as_ref()
                    .map(py_delta_to_iggy_duration)
                    .transpose()?
                    .unwrap_or(defaults.reestablish_after),
            },
        })
    }

    #[getter]
    fn enabled(&self) -> bool {
        self.inner.enabled
    }

    #[gen_stub(override_return_type(type_repr = "builtins.int | None"))]
    #[getter]
    fn max_retries(&self) -> Option<u32> {
        self.inner.max_retries
    }

    #[gen_stub(override_return_type(type_repr = "datetime.timedelta", imports=("datetime")))]
    #[getter]
    fn interval<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyDelta>> {
        iggy_duration_to_py_delta(py, self.inner.interval.get())
    }

    #[gen_stub(override_return_type(type_repr = "datetime.timedelta", imports=("datetime")))]
    #[getter]
    fn reestablish_after<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyDelta>> {
        iggy_duration_to_py_delta(py, self.inner.reestablish_after)
    }

    fn __repr__(&self) -> String {
        let max_retries = match self.inner.max_retries {
            Some(max_retries) => max_retries.to_string(),
            None => "None".to_owned(),
        };
        format!(
            "TcpReconnectionConfig(enabled={}, max_retries={max_retries}, interval={}, reestablish_after={})",
            python_bool(self.inner.enabled),
            duration_repr(self.inner.interval.get()),
            duration_repr(self.inner.reestablish_after),
        )
    }
}

/// Configuration for the TCP transport, accepted by `IggyClient(...)`.
///
/// Every field is keyword-only and optional.
#[gen_stub_pyclass]
#[pyclass(from_py_object)]
#[derive(Clone)]
pub struct TcpConfig {
    inner: Arc<RustTcpClientConfig>,
}

impl TcpConfig {
    /// The configuration in the shape `TcpClient::create` expects.
    pub(crate) fn client_config(&self) -> Arc<RustTcpClientConfig> {
        self.inner.clone()
    }
}

#[gen_stub_pymethods]
#[pymethods]
impl TcpConfig {
    /// Constructs a TCP configuration.
    ///
    /// Args:
    ///     server_address: `host:port` of the Iggy server. Defaults to `127.0.0.1:8090`.
    ///     auto_login: Credentials replayed on every connect. Defaults to `AutoLogin.disabled()`.
    ///     reconnection: Reconnection policy. Defaults to `TcpReconnectionConfig()`.
    ///     heartbeat_interval: Interval of heartbeats sent by the client. Defaults to 5 seconds.
    ///     tls_enabled: Whether to connect over TLS. Defaults to disabled.
    ///     tls_domain: Domain to validate the certificate against. Empty means it is
    ///         taken from `server_address`.
    ///     tls_ca_file: Path to the CA file for TLS. Read only when `tls_enabled`
    ///         and `tls_validate_certificate` are both on; with either one off it
    ///         is kept but never consulted, so pairing it with
    ///         `tls_validate_certificate=False` pins nothing.
    ///     tls_validate_certificate: Whether to validate the server certificate.
    ///         Defaults to validating. Disabling this accepts any certificate the
    ///         server presents, including self-signed and mismatched ones, and
    ///         takes precedence over `tls_ca_file`; intended for local development
    ///         only.
    ///     nodelay: Disable the Nagle algorithm for the TCP socket. Defaults to
    ///         leaving it on.
    ///
    /// Raises:
    ///     ValueError: If `server_address` is not a valid `host:port` pair, if a
    ///         duration is negative, or if `heartbeat_interval` is zero.
    #[new]
    #[pyo3(signature = (
        *,
        server_address=None,
        auto_login=None,
        reconnection=None,
        heartbeat_interval=None,
        tls_enabled=None,
        tls_domain=None,
        tls_ca_file=None,
        tls_validate_certificate=None,
        nodelay=None,
    ))]
    #[allow(clippy::too_many_arguments)]
    fn new(
        #[gen_stub(override_type(type_repr = "builtins.str | None"))] server_address: Option<
            String,
        >,
        #[gen_stub(override_type(type_repr = "AutoLogin | None"))] auto_login: Option<AutoLogin>,
        #[gen_stub(override_type(type_repr = "TcpReconnectionConfig | None"))] reconnection: Option<
            TcpReconnectionConfig,
        >,
        #[gen_stub(override_type(type_repr = "datetime.timedelta | None", imports=("datetime")))]
        heartbeat_interval: Option<Py<PyDelta>>,
        #[gen_stub(override_type(type_repr = "builtins.bool | None"))] tls_enabled: Option<bool>,
        #[gen_stub(override_type(type_repr = "builtins.str | None"))] tls_domain: Option<String>,
        #[gen_stub(override_type(type_repr = "builtins.str | None"))] tls_ca_file: Option<String>,
        #[gen_stub(override_type(type_repr = "builtins.bool | None"))]
        tls_validate_certificate: Option<bool>,
        #[gen_stub(override_type(type_repr = "builtins.bool | None"))] nodelay: Option<bool>,
    ) -> PyResult<Self> {
        // The builder starts from `TcpClientConfig::default()`, and its `build()`
        // trims and validates the address whether or not one was set here.
        let mut builder = TcpClientConfigBuilder::new();
        if let Some(server_address) = server_address {
            builder = builder.with_server_address(server_address);
        }
        let mut inner = builder
            .build()
            .map_err(|e| invalid_address("server_address", e))?;
        if let Some(auto_login) = auto_login {
            inner.auto_login = auto_login.inner;
        }
        if let Some(reconnection) = reconnection {
            inner.reconnection = reconnection.inner;
        }
        if let Some(heartbeat_interval) = heartbeat_interval {
            inner.heartbeat_interval = reject_zero(
                py_delta_to_iggy_duration(&heartbeat_interval)?,
                "heartbeat_interval",
            )?;
        }
        if let Some(tls_enabled) = tls_enabled {
            inner.tls_enabled = tls_enabled;
        }
        if let Some(tls_domain) = tls_domain {
            inner.tls_domain = tls_domain;
        }
        if tls_ca_file.is_some() {
            inner.tls_ca_file = tls_ca_file;
        }
        if let Some(tls_validate_certificate) = tls_validate_certificate {
            inner.tls_validate_certificate = tls_validate_certificate;
        }
        if let Some(nodelay) = nodelay {
            inner.nodelay = nodelay;
        }

        Ok(Self {
            inner: Arc::new(inner),
        })
    }

    #[getter]
    fn server_address(&self) -> String {
        self.inner.server_address.clone()
    }

    #[getter]
    fn auto_login(&self) -> AutoLogin {
        AutoLogin {
            inner: self.inner.auto_login.clone(),
        }
    }

    #[getter]
    fn reconnection(&self) -> TcpReconnectionConfig {
        TcpReconnectionConfig {
            inner: self.inner.reconnection.clone(),
        }
    }

    #[gen_stub(override_return_type(type_repr = "datetime.timedelta", imports=("datetime")))]
    #[getter]
    fn heartbeat_interval<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyDelta>> {
        iggy_duration_to_py_delta(py, self.inner.heartbeat_interval.get())
    }

    #[getter]
    fn tls_enabled(&self) -> bool {
        self.inner.tls_enabled
    }

    #[getter]
    fn tls_domain(&self) -> String {
        self.inner.tls_domain.clone()
    }

    #[gen_stub(override_return_type(type_repr = "builtins.str | None"))]
    #[getter]
    fn tls_ca_file(&self) -> Option<String> {
        self.inner.tls_ca_file.clone()
    }

    #[getter]
    fn tls_validate_certificate(&self) -> bool {
        self.inner.tls_validate_certificate
    }

    #[getter]
    fn nodelay(&self) -> bool {
        self.inner.nodelay
    }

    fn __repr__(&self) -> String {
        let tls_ca_file = match &self.inner.tls_ca_file {
            Some(tls_ca_file) => format!("{tls_ca_file:?}"),
            None => "None".to_owned(),
        };
        format!(
            "TcpConfig(server_address={:?}, auto_login={}, reconnection={}, heartbeat_interval={}, tls_enabled={}, tls_domain={:?}, tls_ca_file={tls_ca_file}, tls_validate_certificate={}, nodelay={})",
            self.inner.server_address,
            self.auto_login().__repr__(),
            self.reconnection().__repr__(),
            duration_repr(self.inner.heartbeat_interval.get()),
            python_bool(self.inner.tls_enabled),
            self.inner.tls_domain,
            python_bool(self.inner.tls_validate_certificate),
            python_bool(self.inner.nodelay),
        )
    }
}

/// How the QUIC client reconnects after the connection to the server is lost.
#[gen_stub_pyclass]
#[pyclass(from_py_object)]
#[derive(Clone)]
pub struct QuicReconnectionConfig {
    pub(crate) inner: RustQuicClientReconnectionConfig,
}

#[gen_stub_pymethods]
#[pymethods]
impl QuicReconnectionConfig {
    /// Constructs a reconnection policy.
    ///
    /// Args:
    ///     enabled: Whether to reconnect at all. Defaults to enabled.
    ///     max_retries: Redials of the configured server address after the first
    ///         attempt, or `None` for unlimited; `0` still makes that first
    ///         attempt. Unlike the TCP transport, QUIC redials the one address
    ///         it was configured with rather than walking a cluster roster, so
    ///         this counts dials. Defaults to unlimited, which means a call
    ///         awaited while the server is down never returns: `connect()`
    ///         waits inside the retry loop, as do `send_messages()` and
    ///         `poll_messages()` once auto-login is configured. Set a finite
    ///         number for request/reply style usage, so a call fails instead.
    ///     interval: Delay before each redial. Defaults to 1 second.
    ///     reestablish_after: Cooldown before redialing after a previously
    ///         successful connection, measured from when it was established, so
    ///         a session that outlived the interval is redialed at once.
    ///         Defaults to 5 seconds.
    ///
    /// Raises:
    ///     ValueError: If a duration is negative, if `max_retries` is outside the
    ///         range of an unsigned 32-bit integer, or if `interval` is zero.
    ///     OverflowError: If `max_retries` does not fit a signed 64-bit integer,
    ///         raised by the underlying conversion before this constructor runs.
    #[new]
    #[pyo3(signature = (*, enabled=None, max_retries=None, interval=None, reestablish_after=None))]
    fn new(
        #[gen_stub(override_type(type_repr = "builtins.bool | None"))] enabled: Option<bool>,
        #[gen_stub(override_type(type_repr = "builtins.int | None"))] max_retries: Option<i64>,
        #[gen_stub(override_type(type_repr = "datetime.timedelta | None", imports=("datetime")))]
        interval: Option<Py<PyDelta>>,
        #[gen_stub(override_type(type_repr = "datetime.timedelta | None", imports=("datetime")))]
        reestablish_after: Option<Py<PyDelta>>,
    ) -> PyResult<Self> {
        let defaults = RustQuicClientReconnectionConfig::default();
        let enabled = enabled.unwrap_or(defaults.enabled);
        let max_retries = max_retries
            .map(|max_retries| u32_param(max_retries, "max_retries"))
            .transpose()?;
        let interval = interval
            .as_ref()
            .map(py_delta_to_iggy_duration)
            .transpose()?
            .map(|interval| reject_zero(interval, "interval"))
            .transpose()?
            .unwrap_or(defaults.interval);
        Ok(Self {
            inner: RustQuicClientReconnectionConfig {
                enabled,
                max_retries,
                interval,
                reestablish_after: reestablish_after
                    .as_ref()
                    .map(py_delta_to_iggy_duration)
                    .transpose()?
                    .unwrap_or(defaults.reestablish_after),
            },
        })
    }

    #[getter]
    fn enabled(&self) -> bool {
        self.inner.enabled
    }

    #[gen_stub(override_return_type(type_repr = "builtins.int | None"))]
    #[getter]
    fn max_retries(&self) -> Option<u32> {
        self.inner.max_retries
    }

    #[gen_stub(override_return_type(type_repr = "datetime.timedelta", imports=("datetime")))]
    #[getter]
    fn interval<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyDelta>> {
        iggy_duration_to_py_delta(py, self.inner.interval.get())
    }

    #[gen_stub(override_return_type(type_repr = "datetime.timedelta", imports=("datetime")))]
    #[getter]
    fn reestablish_after<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyDelta>> {
        iggy_duration_to_py_delta(py, self.inner.reestablish_after)
    }

    fn __repr__(&self) -> String {
        let max_retries = match self.inner.max_retries {
            Some(max_retries) => max_retries.to_string(),
            None => "None".to_owned(),
        };
        format!(
            "QuicReconnectionConfig(enabled={}, max_retries={max_retries}, interval={}, reestablish_after={})",
            python_bool(self.inner.enabled),
            duration_repr(self.inner.interval.get()),
            duration_repr(self.inner.reestablish_after),
        )
    }
}

/// quinn clamps `TransportConfig::initial_mtu` up to this floor rather than
/// rejecting a smaller value, so `QuicConfig` rejects it instead: otherwise the
/// getter would read back a value that is not the one actually in effect.
const QUINN_MIN_INITIAL_MTU: u16 = 1200;

/// Configuration for the QUIC transport, accepted by `IggyClient(...)`.
///
/// Every field is keyword-only and optional.
#[gen_stub_pyclass]
#[pyclass(from_py_object)]
#[derive(Clone)]
pub struct QuicConfig {
    inner: Arc<RustQuicClientConfig>,
}

impl QuicConfig {
    /// The configuration in the shape `QuicClient::create` expects.
    pub(crate) fn client_config(&self) -> Arc<RustQuicClientConfig> {
        self.inner.clone()
    }
}

#[gen_stub_pymethods]
#[pymethods]
impl QuicConfig {
    /// Constructs a QUIC configuration.
    ///
    /// Args:
    ///     server_address: `host:port` of the Iggy server. Defaults to `127.0.0.1:8080`.
    ///     client_address: `host:port` to bind the local UDP socket to. Defaults to
    ///         `127.0.0.1:0`, which binds to any available port. That exact value,
    ///         passed or defaulted, binds `[::1]:0` instead when `server_address`
    ///         resolves to IPv6, so the socket in use may not be the address read
    ///         back here. Any other value binds as given.
    ///     server_name: Server name used for the QUIC/TLS handshake. Defaults to
    ///         `localhost`.
    ///     auto_login: Credentials replayed on every connect. Defaults to `AutoLogin.disabled()`.
    ///     reconnection: Reconnection policy. Defaults to `QuicReconnectionConfig()`.
    ///     heartbeat_interval: Interval of heartbeats sent by the client. Defaults to 5 seconds.
    ///     response_buffer_size: Size of the response buffer in bytes. Defaults to 10 MB.
    ///     max_concurrent_bidi_streams: Maximum number of concurrent bidirectional
    ///         streams. Defaults to 10,000.
    ///     datagram_send_buffer_size: Size of the datagram send buffer in bytes.
    ///         Defaults to 100,000.
    ///     initial_mtu: Initial MTU in bytes. Defaults to 1200.
    ///     send_window: Send window size in bytes. Defaults to 100,000.
    ///     receive_window: Receive window size in bytes. Defaults to 100,000.
    ///     keep_alive_interval: Interval between QUIC keep-alive pings, or a zero
    ///         duration to disable them. Defaults to 5 seconds.
    ///     max_idle_timeout: How long the connection tolerates silence before it is
    ///         considered dead, or a zero duration to use quinn's own default (30
    ///         seconds) instead, since `configure()` skips the setter entirely when
    ///         zero. Defaults to 10 seconds.
    ///     validate_certificate: Whether to validate the server certificate. Defaults
    ///         to disabled; only the TCP transport validates by default.
    ///
    /// Raises:
    ///     ValueError: If `server_address` or `client_address` is not a valid
    ///         `host:port` pair, if a duration is negative, if
    ///         `heartbeat_interval` is zero, if `keep_alive_interval` or
    ///         `max_idle_timeout` is not a whole number of milliseconds, if
    ///         `initial_mtu` is below quinn's minimum of 1200, or if a numeric
    ///         field is outside the range of its underlying wire type.
    ///     OverflowError: If a numeric field does not fit a signed 64-bit integer,
    ///         raised by the underlying conversion before this constructor runs.
    #[new]
    #[pyo3(signature = (
        *,
        server_address=None,
        client_address=None,
        server_name=None,
        auto_login=None,
        reconnection=None,
        heartbeat_interval=None,
        response_buffer_size=None,
        max_concurrent_bidi_streams=None,
        datagram_send_buffer_size=None,
        initial_mtu=None,
        send_window=None,
        receive_window=None,
        keep_alive_interval=None,
        max_idle_timeout=None,
        validate_certificate=None,
    ))]
    #[allow(clippy::too_many_arguments)]
    fn new(
        #[gen_stub(override_type(type_repr = "builtins.str | None"))] server_address: Option<
            String,
        >,
        #[gen_stub(override_type(type_repr = "builtins.str | None"))] client_address: Option<
            String,
        >,
        #[gen_stub(override_type(type_repr = "builtins.str | None"))] server_name: Option<String>,
        #[gen_stub(override_type(type_repr = "AutoLogin | None"))] auto_login: Option<AutoLogin>,
        #[gen_stub(override_type(type_repr = "QuicReconnectionConfig | None"))]
        reconnection: Option<QuicReconnectionConfig>,
        #[gen_stub(override_type(type_repr = "datetime.timedelta | None", imports=("datetime")))]
        heartbeat_interval: Option<Py<PyDelta>>,
        #[gen_stub(override_type(type_repr = "builtins.int | None"))] response_buffer_size: Option<
            i64,
        >,
        #[gen_stub(override_type(type_repr = "builtins.int | None"))]
        max_concurrent_bidi_streams: Option<i64>,
        #[gen_stub(override_type(type_repr = "builtins.int | None"))]
        datagram_send_buffer_size: Option<i64>,
        #[gen_stub(override_type(type_repr = "builtins.int | None"))] initial_mtu: Option<i64>,
        #[gen_stub(override_type(type_repr = "builtins.int | None"))] send_window: Option<i64>,
        #[gen_stub(override_type(type_repr = "builtins.int | None"))] receive_window: Option<i64>,
        #[gen_stub(override_type(type_repr = "datetime.timedelta | None", imports=("datetime")))]
        keep_alive_interval: Option<Py<PyDelta>>,
        #[gen_stub(override_type(type_repr = "datetime.timedelta | None", imports=("datetime")))]
        max_idle_timeout: Option<Py<PyDelta>>,
        #[gen_stub(override_type(type_repr = "builtins.bool | None"))] validate_certificate: Option<
            bool,
        >,
    ) -> PyResult<Self> {
        // The builder starts from `QuicClientConfig::default()`, and its `build()`
        // trims and validates the server address whether or not one was set here.
        let mut builder = QuicClientConfigBuilder::new();
        if let Some(server_address) = server_address {
            builder = builder.with_server_address(server_address);
        }
        let mut inner = builder
            .build()
            .map_err(|e| invalid_address("server_address", e))?;
        if let Some(client_address) = client_address {
            // Trimmed like the server address, but otherwise kept verbatim rather
            // than re-serialized from the parsed `SocketAddr`: `QuicClient::create`
            // compares this against the literal default to decide whether to bind
            // an IPv6 socket for an IPv6 server, and a rewritten string would not
            // match.
            let client_address = client_address.trim();
            client_address
                .parse::<SocketAddr>()
                .map_err(|e| invalid_address("client_address", e))?;
            inner.client_address = client_address.to_owned();
        }
        if let Some(server_name) = server_name {
            inner.server_name = server_name;
        }
        if let Some(auto_login) = auto_login {
            inner.auto_login = auto_login.inner;
        }
        if let Some(reconnection) = reconnection {
            inner.reconnection = reconnection.inner;
        }
        if let Some(heartbeat_interval) = heartbeat_interval {
            inner.heartbeat_interval = reject_zero(
                py_delta_to_iggy_duration(&heartbeat_interval)?,
                "heartbeat_interval",
            )?;
        }
        if let Some(response_buffer_size) = response_buffer_size {
            inner.response_buffer_size = u64_param(response_buffer_size, "response_buffer_size")?;
        }
        if let Some(max_concurrent_bidi_streams) = max_concurrent_bidi_streams {
            inner.max_concurrent_bidi_streams =
                varint_param(max_concurrent_bidi_streams, "max_concurrent_bidi_streams")?;
        }
        if let Some(datagram_send_buffer_size) = datagram_send_buffer_size {
            inner.datagram_send_buffer_size =
                u64_param(datagram_send_buffer_size, "datagram_send_buffer_size")?;
        }
        if let Some(initial_mtu) = initial_mtu {
            let initial_mtu = u16_param(initial_mtu, "initial_mtu")?;
            if initial_mtu < QUINN_MIN_INITIAL_MTU {
                return Err(PyValueError::new_err(format!(
                    "'initial_mtu' must be at least {QUINN_MIN_INITIAL_MTU}; quinn silently \
                     raises anything smaller to that floor, so the getter would no longer \
                     match the value actually in effect"
                )));
            }
            inner.initial_mtu = initial_mtu;
        }
        if let Some(send_window) = send_window {
            inner.send_window = u64_param(send_window, "send_window")?;
        }
        if let Some(receive_window) = receive_window {
            inner.receive_window = varint_param(receive_window, "receive_window")?;
        }
        if let Some(keep_alive_interval) = keep_alive_interval {
            inner.keep_alive_interval =
                py_delta_to_millis(&keep_alive_interval, "keep_alive_interval")?;
        }
        if let Some(max_idle_timeout) = max_idle_timeout {
            inner.max_idle_timeout = py_delta_to_millis(&max_idle_timeout, "max_idle_timeout")?;
        }
        if let Some(validate_certificate) = validate_certificate {
            inner.validate_certificate = validate_certificate;
        }

        Ok(Self {
            inner: Arc::new(inner),
        })
    }

    #[getter]
    fn server_address(&self) -> String {
        self.inner.server_address.clone()
    }

    #[getter]
    fn client_address(&self) -> String {
        self.inner.client_address.clone()
    }

    #[getter]
    fn server_name(&self) -> String {
        self.inner.server_name.clone()
    }

    #[getter]
    fn auto_login(&self) -> AutoLogin {
        AutoLogin {
            inner: self.inner.auto_login.clone(),
        }
    }

    #[getter]
    fn reconnection(&self) -> QuicReconnectionConfig {
        QuicReconnectionConfig {
            inner: self.inner.reconnection.clone(),
        }
    }

    #[gen_stub(override_return_type(type_repr = "datetime.timedelta", imports=("datetime")))]
    #[getter]
    fn heartbeat_interval<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyDelta>> {
        iggy_duration_to_py_delta(py, self.inner.heartbeat_interval.get())
    }

    #[gen_stub(override_return_type(type_repr = "builtins.int"))]
    #[getter]
    fn response_buffer_size(&self) -> u64 {
        self.inner.response_buffer_size
    }

    #[gen_stub(override_return_type(type_repr = "builtins.int"))]
    #[getter]
    fn max_concurrent_bidi_streams(&self) -> u64 {
        self.inner.max_concurrent_bidi_streams
    }

    #[gen_stub(override_return_type(type_repr = "builtins.int"))]
    #[getter]
    fn datagram_send_buffer_size(&self) -> u64 {
        self.inner.datagram_send_buffer_size
    }

    #[gen_stub(override_return_type(type_repr = "builtins.int"))]
    #[getter]
    fn initial_mtu(&self) -> u16 {
        self.inner.initial_mtu
    }

    #[gen_stub(override_return_type(type_repr = "builtins.int"))]
    #[getter]
    fn send_window(&self) -> u64 {
        self.inner.send_window
    }

    #[gen_stub(override_return_type(type_repr = "builtins.int"))]
    #[getter]
    fn receive_window(&self) -> u64 {
        self.inner.receive_window
    }

    #[gen_stub(override_return_type(type_repr = "datetime.timedelta", imports=("datetime")))]
    #[getter]
    fn keep_alive_interval<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyDelta>> {
        millis_to_py_delta(py, self.inner.keep_alive_interval)
    }

    #[gen_stub(override_return_type(type_repr = "datetime.timedelta", imports=("datetime")))]
    #[getter]
    fn max_idle_timeout<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyDelta>> {
        millis_to_py_delta(py, self.inner.max_idle_timeout)
    }

    #[getter]
    fn validate_certificate(&self) -> bool {
        self.inner.validate_certificate
    }

    fn __repr__(&self) -> String {
        format!(
            "QuicConfig(server_address={:?}, client_address={:?}, server_name={:?}, auto_login={}, reconnection={}, heartbeat_interval={}, response_buffer_size={}, max_concurrent_bidi_streams={}, datagram_send_buffer_size={}, initial_mtu={}, send_window={}, receive_window={}, keep_alive_interval={}, max_idle_timeout={}, validate_certificate={})",
            self.inner.server_address,
            self.inner.client_address,
            self.inner.server_name,
            self.auto_login().__repr__(),
            self.reconnection().__repr__(),
            duration_repr(self.inner.heartbeat_interval.get()),
            self.inner.response_buffer_size,
            self.inner.max_concurrent_bidi_streams,
            self.inner.datagram_send_buffer_size,
            self.inner.initial_mtu,
            self.inner.send_window,
            self.inner.receive_window,
            millis_repr(self.inner.keep_alive_interval),
            millis_repr(self.inner.max_idle_timeout),
            python_bool(self.inner.validate_certificate),
        )
    }
}

/// Configuration for the HTTP transport, accepted by `IggyClient(...)`.
///
/// Every field is keyword-only and optional.
///
/// There is no `AutoLogin` and no reconnection policy, and `connect()` does not
/// dial: it only starts the heartbeat, so `login_user(...)` has to follow it.
///
/// HTTP is single-consumer only. `consumer_group(...)` fails with
/// `Feature is unavailable`, and so does a `Consumer.Group(...)` poll unless it
/// names an explicit `partition_id`. With one, the consumer kind is not carried
/// on the HTTP wire, so the poll is served as an ordinary consumer named after
/// the group, with no membership, no partition assignment, and no rebalancing
/// behind it. Pass `Consumer.Single(...)` explicitly.
#[gen_stub_pyclass]
#[pyclass(from_py_object)]
#[derive(Clone)]
pub struct HttpConfig {
    inner: Arc<RustHttpClientConfig>,
}

impl HttpConfig {
    /// The configuration in the shape `HttpClient::create` expects.
    pub(crate) fn client_config(&self) -> Arc<RustHttpClientConfig> {
        self.inner.clone()
    }
}

#[gen_stub_pymethods]
#[pymethods]
impl HttpConfig {
    /// Constructs an HTTP configuration.
    ///
    /// Args:
    ///     api_url: Base URL of the Iggy HTTP API, as `scheme://host[:port]`
    ///         only - no path, query, fragment, or credentials. Defaults to
    ///         `http://127.0.0.1:3000`.
    ///     retries: Number of retries to perform on transient errors, each one
    ///         replaying the full request (including its body) via automatic
    ///         middleware. Defaults to 3. Delivery is therefore at-least-once:
    ///         if the original request actually committed but its response
    ///         was lost (e.g. to a timeout), a retried call applies the same
    ///         operation again. Set to 0 to disable automatic replay and match
    ///         the other transports, which surface the failure instead of
    ///         silently resending.
    ///     jwt: JWT token for A2A (Agent-to-Agent) authentication. Defaults to
    ///         `None`. Stored trimmed, since a token read from a file carries a
    ///         trailing newline that the `Authorization` header value rejects.
    ///         Rejected if empty or whitespace-only: accepting it would make
    ///         `has_jwt` report `True` while every call still fails
    ///         `Unauthenticated`.
    ///     heartbeat_interval: Interval between the client's liveness probes
    ///         (a bare `GET /ping`). Defaults to 5 seconds. Unlike TCP/QUIC,
    ///         HTTP has no persistent connection or session for this to keep
    ///         alive; it only proves the server is reachable.
    ///
    /// Raises:
    ///     ValueError: If `api_url` is not a valid URL, if `retries` is outside
    ///         the range of an unsigned 32-bit integer, if `jwt` is empty or
    ///         whitespace-only, if a duration is negative, or if
    ///         `heartbeat_interval` is zero.
    ///     OverflowError: If `retries` does not fit a signed 64-bit integer,
    ///         raised by the underlying conversion before this constructor runs.
    #[new]
    #[pyo3(signature = (*, api_url=None, retries=None, jwt=None, heartbeat_interval=None))]
    fn new(
        #[gen_stub(override_type(type_repr = "builtins.str | None"))] api_url: Option<String>,
        #[gen_stub(override_type(type_repr = "builtins.int | None"))] retries: Option<i64>,
        #[gen_stub(override_type(type_repr = "builtins.str | None"))] jwt: Option<String>,
        #[gen_stub(override_type(type_repr = "datetime.timedelta | None", imports=("datetime")))]
        heartbeat_interval: Option<Py<PyDelta>>,
    ) -> PyResult<Self> {
        // The builder starts from `HttpClientConfig::default()`, and its `build()`
        // trims and validates the API URL whether or not one was set here.
        let mut builder = HttpClientConfigBuilder::new();
        if let Some(api_url) = api_url {
            builder = builder.with_api_url(api_url);
        }
        let mut inner = builder
            .build()
            .map_err(|e| PyValueError::new_err(format!("'api_url' is not a valid URL: {e}")))?;
        if let Some(retries) = retries {
            inner.retries = u32_param(retries, "retries")?;
        }
        if let Some(jwt) = jwt {
            let jwt = jwt.trim();
            if jwt.is_empty() {
                return Err(PyValueError::new_err(
                    "'jwt' must not be empty or whitespace-only",
                ));
            }
            inner.jwt = Some(jwt.to_owned());
        }
        if let Some(heartbeat_interval) = heartbeat_interval {
            inner.heartbeat_interval = reject_zero(
                py_delta_to_iggy_duration(&heartbeat_interval)?,
                "heartbeat_interval",
            )?;
        }

        Ok(Self {
            inner: Arc::new(inner),
        })
    }

    #[getter]
    fn api_url(&self) -> String {
        self.inner.api_url.clone()
    }

    #[getter]
    fn retries(&self) -> u32 {
        self.inner.retries
    }

    /// Whether a JWT is configured, without exposing the token itself.
    #[getter]
    fn has_jwt(&self) -> bool {
        self.inner.jwt.is_some()
    }

    #[gen_stub(override_return_type(type_repr = "datetime.timedelta", imports=("datetime")))]
    #[getter]
    fn heartbeat_interval<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyDelta>> {
        iggy_duration_to_py_delta(py, self.inner.heartbeat_interval.get())
    }

    fn __repr__(&self) -> String {
        let jwt = if self.inner.jwt.is_some() {
            "..."
        } else {
            "None"
        };
        format!(
            "HttpConfig(api_url={:?}, retries={}, jwt={jwt}, heartbeat_interval={})",
            self.inner.api_url,
            self.inner.retries,
            duration_repr(self.inner.heartbeat_interval.get()),
        )
    }
}

/// How the WebSocket client reconnects after the connection to the server is lost.
#[gen_stub_pyclass]
#[pyclass(from_py_object)]
#[derive(Clone)]
pub struct WebSocketReconnectionConfig {
    pub(crate) inner: RustWebSocketClientReconnectionConfig,
}

#[gen_stub_pymethods]
#[pymethods]
impl WebSocketReconnectionConfig {
    /// Constructs a reconnection policy.
    ///
    /// Args:
    ///     enabled: Whether to reconnect at all. Defaults to enabled.
    ///     max_retries: Redials of the configured server address after the first
    ///         attempt, or `None` for unlimited; `0` still makes that first
    ///         attempt. Unlike the TCP transport, WebSocket redials the one
    ///         address it was configured with rather than walking a cluster
    ///         roster, so this counts dials. Defaults to unlimited, which means
    ///         a call awaited while the server is down never returns:
    ///         `connect()` waits inside the retry loop, as do `send_messages()`
    ///         and `poll_messages()` once auto-login is configured. Set a finite
    ///         number for request/reply style usage, so a call fails instead.
    ///     interval: Delay before each redial. Defaults to 1 second.
    ///     reestablish_after: Cooldown before redialing after a previously
    ///         successful connection, measured from when it was established, so
    ///         a session that outlived the interval is redialed at once. Applied
    ///         from the first redial onward, not to the initial connect.
    ///         Defaults to 5 seconds.
    ///
    /// Raises:
    ///     ValueError: If a duration is negative, if `max_retries` is outside the
    ///         range of an unsigned 32-bit integer, or if `interval` is zero.
    ///     OverflowError: If `max_retries` does not fit a signed 64-bit integer,
    ///         raised by the underlying conversion before this constructor runs.
    #[new]
    #[pyo3(signature = (*, enabled=None, max_retries=None, interval=None, reestablish_after=None))]
    fn new(
        #[gen_stub(override_type(type_repr = "builtins.bool | None"))] enabled: Option<bool>,
        #[gen_stub(override_type(type_repr = "builtins.int | None"))] max_retries: Option<i64>,
        #[gen_stub(override_type(type_repr = "datetime.timedelta | None", imports=("datetime")))]
        interval: Option<Py<PyDelta>>,
        #[gen_stub(override_type(type_repr = "datetime.timedelta | None", imports=("datetime")))]
        reestablish_after: Option<Py<PyDelta>>,
    ) -> PyResult<Self> {
        let defaults = RustWebSocketClientReconnectionConfig::default();
        let enabled = enabled.unwrap_or(defaults.enabled);
        let max_retries = max_retries
            .map(|max_retries| u32_param(max_retries, "max_retries"))
            .transpose()?;
        let interval = interval
            .as_ref()
            .map(py_delta_to_iggy_duration)
            .transpose()?
            .map(|interval| reject_zero(interval, "interval"))
            .transpose()?
            .unwrap_or(defaults.interval);
        Ok(Self {
            inner: RustWebSocketClientReconnectionConfig {
                enabled,
                max_retries,
                interval,
                reestablish_after: reestablish_after
                    .as_ref()
                    .map(py_delta_to_iggy_duration)
                    .transpose()?
                    .unwrap_or(defaults.reestablish_after),
            },
        })
    }

    #[getter]
    fn enabled(&self) -> bool {
        self.inner.enabled
    }

    #[gen_stub(override_return_type(type_repr = "builtins.int | None"))]
    #[getter]
    fn max_retries(&self) -> Option<u32> {
        self.inner.max_retries
    }

    #[gen_stub(override_return_type(type_repr = "datetime.timedelta", imports=("datetime")))]
    #[getter]
    fn interval<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyDelta>> {
        iggy_duration_to_py_delta(py, self.inner.interval.get())
    }

    #[gen_stub(override_return_type(type_repr = "datetime.timedelta", imports=("datetime")))]
    #[getter]
    fn reestablish_after<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyDelta>> {
        iggy_duration_to_py_delta(py, self.inner.reestablish_after)
    }

    fn __repr__(&self) -> String {
        let max_retries = match self.inner.max_retries {
            Some(max_retries) => max_retries.to_string(),
            None => "None".to_owned(),
        };
        format!(
            "WebSocketReconnectionConfig(enabled={}, max_retries={max_retries}, interval={}, reestablish_after={})",
            python_bool(self.inner.enabled),
            duration_repr(self.inner.interval.get()),
            duration_repr(self.inner.reestablish_after),
        )
    }
}

/// Frame- and buffer-level options passed through to the underlying WebSocket
/// implementation, accepted by `WebSocketConfig`'s `framing` argument.
///
/// Every field is keyword-only and optional; unset fields fall back to the
/// underlying WebSocket library's own defaults.
#[gen_stub_pyclass]
#[pyclass(from_py_object)]
#[derive(Clone)]
pub struct WebSocketFramingConfig {
    pub(crate) inner: RustWebSocketFramingConfig,
}

#[gen_stub_pymethods]
#[pymethods]
impl WebSocketFramingConfig {
    /// Constructs a WebSocket framing configuration.
    ///
    /// Args:
    ///     read_buffer_size: Read buffer size in bytes. Defaults to 128 KiB.
    ///     write_buffer_size: Write buffer size in bytes. Defaults to 128 KiB.
    ///     max_write_buffer_size: Maximum write buffer size in bytes. Defaults to
    ///         unbounded, which reads back as the largest value a pointer-sized
    ///         unsigned integer holds rather than as `None`.
    ///     max_message_size: Maximum message size in bytes, or an explicit `None`
    ///         to lift the limit entirely. Omitting the argument is not the same
    ///         as passing `None`: it keeps the underlying default of 64 MiB.
    ///         Lifting the limit lets a peer queue an arbitrarily large message
    ///         in memory, so prefer a finite value.
    ///     max_frame_size: Maximum frame size in bytes, or an explicit `None` to
    ///         lift the limit entirely. Omitting the argument keeps the
    ///         underlying default of 16 MiB, with the same caveat as
    ///         `max_message_size`.
    ///     accept_unmasked_frames: Whether to accept unmasked frames. Defaults to
    ///         `False`; clients should typically keep this off for RFC compliance.
    ///
    /// Raises:
    ///     ValueError: If a numeric field is outside the range of a pointer-sized
    ///         unsigned integer, or if `max_write_buffer_size` does not come out
    ///         greater than `write_buffer_size`. tungstenite enforces the same
    ///         invariant with an `assert!` at connect time, which would otherwise
    ///         surface as an unrecoverable Rust panic instead of a `ValueError`.
    ///     OverflowError: If a numeric field does not fit a signed 128-bit integer,
    ///         raised by the underlying conversion before this constructor runs.
    #[new]
    #[pyo3(signature = (
        *,
        read_buffer_size=None,
        write_buffer_size=None,
        max_write_buffer_size=None,
        max_message_size=64 << 20,
        max_frame_size=16 << 20,
        accept_unmasked_frames=None,
    ))]
    fn new(
        #[gen_stub(override_type(type_repr = "builtins.int | None"))] read_buffer_size: Option<
            i128,
        >,
        #[gen_stub(override_type(type_repr = "builtins.int | None"))] write_buffer_size: Option<
            i128,
        >,
        #[gen_stub(override_type(type_repr = "builtins.int | None"))] max_write_buffer_size: Option<
            i128,
        >,
        #[gen_stub(override_type(type_repr = "builtins.int | None"))] max_message_size: Option<
            i128,
        >,
        #[gen_stub(override_type(type_repr = "builtins.int | None"))] max_frame_size: Option<i128>,
        #[gen_stub(override_type(type_repr = "builtins.bool | None"))]
        accept_unmasked_frames: Option<bool>,
    ) -> PyResult<Self> {
        let mut inner = RustWebSocketFramingConfig::default();
        if let Some(read_buffer_size) = read_buffer_size {
            inner.read_buffer_size = Some(usize_param(read_buffer_size, "read_buffer_size")?);
        }
        if let Some(write_buffer_size) = write_buffer_size {
            inner.write_buffer_size = Some(usize_param(write_buffer_size, "write_buffer_size")?);
        }
        if let Some(max_write_buffer_size) = max_write_buffer_size {
            inner.max_write_buffer_size =
                Some(usize_param(max_write_buffer_size, "max_write_buffer_size")?);
        }
        // Assigned unconditionally, unlike the buffer sizes above: `None` here
        // means "no limit", and pyo3 cannot tell an omitted argument from an
        // explicit `None` on its own. The signature defaults carry the
        // underlying limits instead, so omission lands on `Some(default)` and
        // only an explicit `None` reaches this as `None`.
        inner.max_message_size = max_message_size
            .map(|max_message_size| usize_param(max_message_size, "max_message_size"))
            .transpose()?;
        inner.max_frame_size = max_frame_size
            .map(|max_frame_size| usize_param(max_frame_size, "max_frame_size"))
            .transpose()?;
        if let Some(accept_unmasked_frames) = accept_unmasked_frames {
            inner.accept_unmasked_frames = accept_unmasked_frames;
        }
        if let (Some(write_buffer_size), Some(max_write_buffer_size)) =
            (inner.write_buffer_size, inner.max_write_buffer_size)
            && max_write_buffer_size <= write_buffer_size
        {
            return Err(PyValueError::new_err(format!(
                "'max_write_buffer_size' ({max_write_buffer_size}) must be greater than \
                 'write_buffer_size' ({write_buffer_size})"
            )));
        }

        Ok(Self { inner })
    }

    #[gen_stub(override_return_type(type_repr = "builtins.int | None"))]
    #[getter]
    fn read_buffer_size(&self) -> Option<usize> {
        self.inner.read_buffer_size
    }

    #[gen_stub(override_return_type(type_repr = "builtins.int | None"))]
    #[getter]
    fn write_buffer_size(&self) -> Option<usize> {
        self.inner.write_buffer_size
    }

    #[gen_stub(override_return_type(type_repr = "builtins.int | None"))]
    #[getter]
    fn max_write_buffer_size(&self) -> Option<usize> {
        self.inner.max_write_buffer_size
    }

    #[gen_stub(override_return_type(type_repr = "builtins.int | None"))]
    #[getter]
    fn max_message_size(&self) -> Option<usize> {
        self.inner.max_message_size
    }

    #[gen_stub(override_return_type(type_repr = "builtins.int | None"))]
    #[getter]
    fn max_frame_size(&self) -> Option<usize> {
        self.inner.max_frame_size
    }

    #[getter]
    fn accept_unmasked_frames(&self) -> bool {
        self.inner.accept_unmasked_frames
    }

    fn __repr__(&self) -> String {
        let optional_usize = |value: Option<usize>| match value {
            Some(value) => value.to_string(),
            None => "None".to_owned(),
        };
        format!(
            "WebSocketFramingConfig(read_buffer_size={}, write_buffer_size={}, max_write_buffer_size={}, max_message_size={}, max_frame_size={}, accept_unmasked_frames={})",
            optional_usize(self.inner.read_buffer_size),
            optional_usize(self.inner.write_buffer_size),
            optional_usize(self.inner.max_write_buffer_size),
            optional_usize(self.inner.max_message_size),
            optional_usize(self.inner.max_frame_size),
            python_bool(self.inner.accept_unmasked_frames),
        )
    }
}

/// Configuration for the WebSocket transport, accepted by `IggyClient(...)`.
///
/// Every field is keyword-only and optional.
#[gen_stub_pyclass]
#[pyclass(from_py_object)]
#[derive(Clone)]
pub struct WebSocketConfig {
    inner: Arc<RustWebSocketClientConfig>,
}

impl WebSocketConfig {
    /// The configuration in the shape `WebSocketClient::create` expects.
    pub(crate) fn client_config(&self) -> Arc<RustWebSocketClientConfig> {
        self.inner.clone()
    }
}

#[gen_stub_pymethods]
#[pymethods]
impl WebSocketConfig {
    /// Constructs a WebSocket configuration.
    ///
    /// Args:
    ///     server_address: `host:port` of the Iggy server. Defaults to `127.0.0.1:8092`.
    ///     auto_login: Credentials replayed on every connect. Defaults to `AutoLogin.disabled()`.
    ///     reconnection: Reconnection policy. Defaults to `WebSocketReconnectionConfig()`.
    ///     heartbeat_interval: Interval of heartbeats sent by the client. Defaults to 5 seconds.
    ///     framing: Frame- and buffer-level options. Defaults to `WebSocketFramingConfig()`.
    ///     tls_enabled: Whether to connect over TLS. Defaults to disabled.
    ///     tls_domain: Domain to validate the certificate against. Defaults to
    ///         `localhost`. Empty means it is taken from the IP `server_address`
    ///         resolves to.
    ///     tls_ca_file: Path to the CA file for TLS. Read only when `tls_enabled`
    ///         and `tls_validate_certificate` are both on; with either one off it
    ///         is kept but never consulted, so pairing it with
    ///         `tls_validate_certificate=False` pins nothing.
    ///     tls_validate_certificate: Whether to validate the server certificate.
    ///         Defaults to `False`; only the TCP transport validates by default.
    ///         Disabling this accepts any certificate the server presents,
    ///         including self-signed and mismatched ones, and takes precedence
    ///         over `tls_ca_file`.
    ///
    /// Raises:
    ///     ValueError: If `server_address` is not a valid `host:port` pair, if a
    ///         duration is negative, or if `heartbeat_interval` is zero.
    #[new]
    #[pyo3(signature = (
        *,
        server_address=None,
        auto_login=None,
        reconnection=None,
        heartbeat_interval=None,
        framing=None,
        tls_enabled=None,
        tls_domain=None,
        tls_ca_file=None,
        tls_validate_certificate=None,
    ))]
    #[allow(clippy::too_many_arguments)]
    fn new(
        #[gen_stub(override_type(type_repr = "builtins.str | None"))] server_address: Option<
            String,
        >,
        #[gen_stub(override_type(type_repr = "AutoLogin | None"))] auto_login: Option<AutoLogin>,
        #[gen_stub(override_type(type_repr = "WebSocketReconnectionConfig | None"))]
        reconnection: Option<WebSocketReconnectionConfig>,
        #[gen_stub(override_type(type_repr = "datetime.timedelta | None", imports=("datetime")))]
        heartbeat_interval: Option<Py<PyDelta>>,
        #[gen_stub(override_type(type_repr = "WebSocketFramingConfig | None"))] framing: Option<
            WebSocketFramingConfig,
        >,
        #[gen_stub(override_type(type_repr = "builtins.bool | None"))] tls_enabled: Option<bool>,
        #[gen_stub(override_type(type_repr = "builtins.str | None"))] tls_domain: Option<String>,
        #[gen_stub(override_type(type_repr = "builtins.str | None"))] tls_ca_file: Option<String>,
        #[gen_stub(override_type(type_repr = "builtins.bool | None"))]
        tls_validate_certificate: Option<bool>,
    ) -> PyResult<Self> {
        // The builder starts from `WebSocketClientConfig::default()`, and its
        // `build()` trims and validates the address whether or not one was set here.
        let mut builder = WebSocketClientConfigBuilder::new();
        if let Some(server_address) = server_address {
            builder = builder.with_server_address(server_address);
        }
        let mut inner = builder
            .build()
            .map_err(|e| invalid_address("server_address", e))?;
        if let Some(auto_login) = auto_login {
            inner.auto_login = auto_login.inner;
        }
        if let Some(reconnection) = reconnection {
            inner.reconnection = reconnection.inner;
        }
        if let Some(heartbeat_interval) = heartbeat_interval {
            inner.heartbeat_interval = reject_zero(
                py_delta_to_iggy_duration(&heartbeat_interval)?,
                "heartbeat_interval",
            )?;
        }
        if let Some(framing) = framing {
            inner.ws_config = framing.inner;
        }
        if let Some(tls_enabled) = tls_enabled {
            inner.tls_enabled = tls_enabled;
        }
        if let Some(tls_domain) = tls_domain {
            inner.tls_domain = tls_domain;
        }
        if tls_ca_file.is_some() {
            inner.tls_ca_file = tls_ca_file;
        }
        if let Some(tls_validate_certificate) = tls_validate_certificate {
            inner.tls_validate_certificate = tls_validate_certificate;
        }

        Ok(Self {
            inner: Arc::new(inner),
        })
    }

    #[getter]
    fn server_address(&self) -> String {
        self.inner.server_address.clone()
    }

    #[getter]
    fn auto_login(&self) -> AutoLogin {
        AutoLogin {
            inner: self.inner.auto_login.clone(),
        }
    }

    #[getter]
    fn reconnection(&self) -> WebSocketReconnectionConfig {
        WebSocketReconnectionConfig {
            inner: self.inner.reconnection.clone(),
        }
    }

    #[gen_stub(override_return_type(type_repr = "datetime.timedelta", imports=("datetime")))]
    #[getter]
    fn heartbeat_interval<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyDelta>> {
        iggy_duration_to_py_delta(py, self.inner.heartbeat_interval.get())
    }

    #[getter]
    fn framing(&self) -> WebSocketFramingConfig {
        WebSocketFramingConfig {
            inner: self.inner.ws_config.clone(),
        }
    }

    #[getter]
    fn tls_enabled(&self) -> bool {
        self.inner.tls_enabled
    }

    #[getter]
    fn tls_domain(&self) -> String {
        self.inner.tls_domain.clone()
    }

    #[gen_stub(override_return_type(type_repr = "builtins.str | None"))]
    #[getter]
    fn tls_ca_file(&self) -> Option<String> {
        self.inner.tls_ca_file.clone()
    }

    #[getter]
    fn tls_validate_certificate(&self) -> bool {
        self.inner.tls_validate_certificate
    }

    fn __repr__(&self) -> String {
        let tls_ca_file = match &self.inner.tls_ca_file {
            Some(tls_ca_file) => format!("{tls_ca_file:?}"),
            None => "None".to_owned(),
        };
        format!(
            "WebSocketConfig(server_address={:?}, auto_login={}, reconnection={}, heartbeat_interval={}, framing={}, tls_enabled={}, tls_domain={:?}, tls_ca_file={tls_ca_file}, tls_validate_certificate={})",
            self.inner.server_address,
            self.auto_login().__repr__(),
            self.reconnection().__repr__(),
            duration_repr(self.inner.heartbeat_interval.get()),
            self.framing().__repr__(),
            python_bool(self.inner.tls_enabled),
            self.inner.tls_domain,
            python_bool(self.inner.tls_validate_certificate),
        )
    }
}

fn python_bool(value: bool) -> &'static str {
    if value { "True" } else { "False" }
}

/// Rejects an address that is not a valid `host:port`, naming the argument it
/// came from: neither the builder's error nor `SocketAddr`'s mentions which one.
fn invalid_address(parameter: &str, error: impl Display) -> PyErr {
    PyValueError::new_err(format!("'{parameter}' is not a valid 'host:port': {error}"))
}

/// Converts a Python int to the unsigned 32-bit integer `max_retries`/`retries`
/// expect, naming the parameter in the error so a caller can tell which
/// argument was out of range. A value too large even for `i64` still raises
/// pyo3's own unnamed `OverflowError` before this ever runs.
fn u32_param(value: i64, parameter: &str) -> PyResult<u32> {
    u32::try_from(value).map_err(|_| {
        PyValueError::new_err(format!("'{parameter}' must be between 0 and {}", u32::MAX))
    })
}

/// Converts a Python int to the unsigned 64-bit integer a QUIC transport
/// field expects, naming the parameter in the error so a caller can tell
/// which argument was out of range. The bound in the message is `i64::MAX`
/// rather than `u64::MAX` because pyo3 extracts the argument as an `i64`
/// first: anything above that never reaches here, raising `OverflowError`
/// on the way in. Every one of these fields is a buffer or window size, so
/// the unreachable half of the range has no practical use.
fn u64_param(value: i64, parameter: &str) -> PyResult<u64> {
    u64::try_from(value).map_err(|_| {
        PyValueError::new_err(format!("'{parameter}' must be between 0 and {}", i64::MAX))
    })
}

/// Converts a Python int to the unsigned 16-bit integer `initial_mtu` expects.
fn u16_param(value: i64, parameter: &str) -> PyResult<u16> {
    u16::try_from(value).map_err(|_| {
        PyValueError::new_err(format!("'{parameter}' must be between 0 and {}", u16::MAX))
    })
}

/// Converts a Python int to a `u64` that also fits `quinn::VarInt` (max
/// `2^62 - 1`), which `max_concurrent_bidi_streams` and `receive_window` are
/// narrowed into when the connection is configured. A `u64` in range for
/// `u64::MAX` but not `VarInt::MAX` would otherwise only fail there, as an
/// opaque `RuntimeError` instead of a `ValueError` naming the argument.
fn varint_param(value: i64, parameter: &str) -> PyResult<u64> {
    const VARINT_MAX: u64 = (1u64 << 62) - 1;
    let value = u64_param(value, parameter)?;
    if value > VARINT_MAX {
        return Err(PyValueError::new_err(format!(
            "'{parameter}' must be between 0 and {VARINT_MAX}"
        )));
    }
    Ok(value)
}

/// Converts a Python int to the unsigned pointer-sized integer a WebSocket
/// framing field expects, naming the parameter in the error so a caller can
/// tell which argument was out of range. Extracted as an `i128` rather than an
/// `i64` so the whole `usize` range survives the way in: `max_write_buffer_size`
/// defaults to `usize::MAX`, which an `i64` parameter would refuse to take back
/// with an unnamed `OverflowError`, breaking `eval(repr(config))`.
fn usize_param(value: i128, parameter: &str) -> PyResult<usize> {
    usize::try_from(value).map_err(|_| {
        PyValueError::new_err(format!(
            "'{parameter}' must be between 0 and {}",
            usize::MAX
        ))
    })
}

/// What `IggyClient(...)` accepts: a bare `host:port`, a full `TcpConfig`, a
/// `QuicConfig` for the QUIC transport, an `HttpConfig` for the HTTP transport,
/// or a `WebSocketConfig` for the WebSocket transport.
#[derive(FromPyObject)]
pub enum PyClientConfig {
    #[pyo3(transparent)]
    Tcp(TcpConfig),
    #[pyo3(transparent)]
    Quic(QuicConfig),
    #[pyo3(transparent)]
    Http(HttpConfig),
    #[pyo3(transparent)]
    WebSocket(WebSocketConfig),
    #[pyo3(transparent, annotation = "str")]
    ServerAddress(String),
}
impl_stub_type!(PyClientConfig = TcpConfig | QuicConfig | HttpConfig | WebSocketConfig | String);

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

    /// Mirrors the literal in `WebSocketFramingConfig::new`'s signature.
    const DEFAULT_MAX_MESSAGE_SIZE: usize = 64 << 20;

    /// Mirrors the literal in `WebSocketFramingConfig::new`'s signature.
    const DEFAULT_MAX_FRAME_SIZE: usize = 16 << 20;

    /// The signature defaults have to be literals for the generated stub to stay
    /// valid Python, so nothing but this test stops them drifting from the SDK
    /// (and so from tungstenite) on a dependency bump.
    #[test]
    fn defaults_should_match_the_sdk() {
        let defaults = RustWebSocketFramingConfig::default();

        assert_eq!(
            defaults.max_message_size,
            Some(DEFAULT_MAX_MESSAGE_SIZE),
            "'max_message_size' drifted from the SDK, update the literal in \
             WebSocketFramingConfig::new's signature too"
        );
        assert_eq!(
            defaults.max_frame_size,
            Some(DEFAULT_MAX_FRAME_SIZE),
            "'max_frame_size' drifted from the SDK, update the literal in \
             WebSocketFramingConfig::new's signature too"
        );
        assert!(
            defaults.write_buffer_size.is_some(),
            "'write_buffer_size' lost its default, so the write buffer invariant \
             check in WebSocketFramingConfig::new would stop running"
        );
        assert!(
            defaults.max_write_buffer_size.is_some(),
            "'max_write_buffer_size' lost its default, so the write buffer \
             invariant check in WebSocketFramingConfig::new would stop running"
        );
    }
}
