"""
Everything within that module is off the semver guarantees.
You use it, you deal with unexpected breakage. Anytime, anywhere.
You'd be better off using cryptography directly.

This module serve exclusively qh3 interests. You have been warned.
"""

from __future__ import annotations

from enum import Enum
from typing import Any, Sequence

class DecompressionFailed(Exception): ...
class DecoderStreamError(Exception): ...
class EncoderStreamError(Exception): ...
class StreamBlocked(Exception): ...

class QpackDecoder:
    def __init__(self, max_table_capacity: int, blocked_streams: int) -> None: ...
    def feed_encoder(self, data: bytes) -> None: ...
    def feed_header(
        self, stream_id: int, data: bytes
    ) -> tuple[bytes, list[tuple[bytes, bytes]]]: ...
    def resume_header(
        self, stream_id: int
    ) -> tuple[bytes, list[tuple[bytes, bytes]]]: ...

class QpackEncoder:
    def apply_settings(
        self, max_table_capacity: int, dyn_table_capacity: int, blocked_streams: int
    ) -> bytes: ...
    def encode(
        self, stream_id: int, headers: list[tuple[bytes, bytes]]
    ) -> tuple[bytes, bytes]: ...
    def feed_decoder(self, data: bytes) -> None: ...

class AeadChaCha20Poly1305:
    def __init__(self, key: bytes, iv: bytes) -> None: ...
    def encrypt(
        self, packet_number: int, data: bytes, associated_data: bytes
    ) -> bytes: ...
    def decrypt(
        self, packet_number: int, data: bytes, associated_data: bytes
    ) -> bytes: ...

class AeadAes256Gcm:
    def __init__(self, key: bytes, iv: bytes) -> None: ...
    def encrypt(
        self, packet_number: int, data: bytes, associated_data: bytes
    ) -> bytes: ...
    def decrypt(
        self, packet_number: int, data: bytes, associated_data: bytes
    ) -> bytes: ...

class AeadAes128Gcm:
    def __init__(self, key: bytes, iv: bytes) -> None: ...
    def encrypt(
        self, packet_number: int, data: bytes, associated_data: bytes
    ) -> bytes: ...
    def encrypt_with_nonce(
        self, nonce: bytes, data: bytes, associated_data: bytes
    ) -> bytes: ...
    def decrypt(
        self, packet_number: int, data: bytes, associated_data: bytes
    ) -> bytes: ...

class ServerVerifier:
    def __init__(self, authorities: list[bytes]) -> None: ...
    def verify(
        self,
        peer: bytes,
        intermediaries: list[bytes],
        server_name: str,
        ocsp_response: bytes,
    ) -> None: ...

class TlsCertUsage(Enum):
    ServerAuth = 0
    ClientAuth = 1
    Both = 2
    Other = 3

class Certificate:
    """
    A (very) straightforward class to expose a parsed X509 certificate.
    This is hazardous material, nothing in there is guaranteed to
    remain backward compatible.

    Use with care...
    """

    def __init__(self, certificate_der: bytes) -> None: ...
    @property
    def subject(self):
        list[tuple[str, str, bytes]]
    @property
    def issuer(self):
        list[tuple[str, str, bytes]]
    @property
    def not_valid_after(self) -> int: ...
    @property
    def not_valid_before(self) -> int: ...
    @property
    def serial_number(self) -> str: ...
    def get_extension_for_oid(self, oid: str) -> list[tuple[str, bool, bytes]]: ...
    @property
    def version(self) -> int: ...
    def get_ocsp_endpoints(self) -> list[bytes]: ...
    def get_crl_endpoints(self) -> list[bytes]: ...
    def get_issuer_endpoints(self) -> list[bytes]: ...
    def get_subject_alt_names(self) -> list[bytes]: ...
    def public_bytes(self) -> bytes: ...
    def public_key(self) -> bytes: ...
    @property
    def self_signed(self) -> bool: ...
    @property
    def is_ca(self) -> bool: ...
    @property
    def usage(self) -> TlsCertUsage: ...
    def serialize(self) -> bytes: ...
    @staticmethod
    def deserialize(src: bytes) -> Certificate: ...

class Rsa:
    """
    This binding host a RSA Private/Public Keys.
    Use Oaep (padding) + SHA256 under. Not customizable.
    """

    def __init__(self, key_size: int) -> None: ...
    def encrypt(self, data: bytes) -> bytes: ...
    def decrypt(self, data: bytes) -> bytes: ...

class EcPrivateKey:
    def __init__(self, der_key: bytes, curve_type: int, is_pkcs8: bool) -> None: ...
    def public_key(self) -> bytes: ...
    def sign(self, data: bytes) -> bytes: ...
    @property
    def curve_type(self) -> int: ...

class Ed25519PrivateKey:
    def __init__(self, pkcs8: bytes) -> None: ...
    def public_key(self) -> bytes: ...
    def sign(self, data: bytes) -> bytes: ...

class DsaPrivateKey:
    def __init__(self, pkcs8: bytes) -> None: ...
    def public_key(self) -> bytes: ...
    def sign(self, data: bytes) -> bytes: ...

class RsaPrivateKey:
    def __init__(self, pkcs8: bytes) -> None: ...
    def public_key(self) -> bytes: ...
    def sign(self, data: bytes, padding, hash_size: int) -> bytes: ...

def verify_with_public_key(
    public_key_raw: bytes, algorithm: int, message: bytes, signature: bytes
) -> None: ...

class X25519ML768KeyExchange:
    def __init__(self) -> None: ...
    def public_key(self) -> bytes: ...
    def exchange(self, peer_public_key: bytes) -> bytes: ...
    def shared_ciphertext(self) -> bytes: ...

class X25519KeyExchange:
    def __init__(self) -> None: ...
    def public_key(self) -> bytes: ...
    def exchange(self, peer_public_key: bytes) -> bytes: ...

class ECDHP256KeyExchange:
    def __init__(self) -> None: ...
    def public_key(self) -> bytes: ...
    def exchange(self, peer_public_key: bytes) -> bytes: ...

class ECDHP384KeyExchange:
    def __init__(self) -> None: ...
    def public_key(self) -> bytes: ...
    def exchange(self, peer_public_key: bytes) -> bytes: ...

class ECDHP521KeyExchange:
    def __init__(self) -> None: ...
    def public_key(self) -> bytes: ...
    def exchange(self, peer_public_key: bytes) -> bytes: ...

class HpkeContext:
    """
    HPKE sender context for Encrypted Client Hello (ECH).
    Wraps rustls HPKE implementation backed by aws-lc-rs.
    Uses SetupBaseS to create a context that can seal multiple messages.
    """

    def __init__(
        self,
        kem_id: int,
        kdf_id: int,
        aead_id: int,
        public_key: bytes,
        info: bytes,
    ) -> None: ...
    def enc(self) -> bytes: ...
    def seal(self, aad: bytes, plaintext: bytes) -> bytes: ...

class CryptoError(Exception): ...

class KeyType(Enum):
    ECDSA_P256 = 0
    ECDSA_P384 = 1
    ECDSA_P521 = 2
    ED25519 = 3
    DSA = 4
    RSA = 5

class PrivateKeyInfo:
    """
    Load a PEM private key and extract valuable info from it.
    Does two things, provide a DER encoded key and hint
    toward its nature (eg. EC, RSA, DSA, etc...)
    """

    def __init__(self, raw_pem_content: bytes, password: bytes | None) -> None: ...
    def public_bytes(self) -> bytes: ...
    def get_type(self) -> KeyType: ...

class SelfSignedCertificateError(Exception): ...
class InvalidNameCertificateError(Exception): ...
class ExpiredCertificateError(Exception): ...
class UnacceptableCertificateError(Exception): ...
class SignatureError(Exception): ...

class QUICHeaderProtection:
    def __init__(self, algorithm: str, key: bytes) -> None: ...
    def apply(self, plain_header: bytes, protected_payload: bytes) -> bytes: ...
    def remove(self, packet: bytes, pn_offset: int) -> tuple[bytes, int]: ...
    def mask(self, sample: bytes) -> bytes: ...

class ReasonFlags(Enum):
    unspecified = 0
    key_compromise = 1
    ca_compromise = 2
    affiliation_changed = 3
    superseded = 4
    cessation_of_operation = 5
    certificate_hold = 6
    privilege_withdrawn = 9
    aa_compromise = 10
    remove_from_crl = 8

class OCSPResponseStatus(Enum):
    SUCCESSFUL = 0
    MALFORMED_REQUEST = 1
    INTERNAL_ERROR = 2
    TRY_LATER = 3
    SIG_REQUIRED = 5
    UNAUTHORIZED = 6

class OCSPCertStatus(Enum):
    GOOD = 0
    REVOKED = 1
    UNKNOWN = 2

class OCSPResponse:
    def __init__(self, raw_response: bytes) -> None: ...
    @property
    def next_update(self) -> int: ...
    @property
    def response_status(self) -> OCSPResponseStatus: ...
    @property
    def certificate_status(self) -> OCSPCertStatus: ...
    @property
    def revocation_reason(self) -> ReasonFlags | None: ...
    def serialize(self) -> bytes: ...
    @staticmethod
    def deserialize(src: bytes) -> OCSPResponse: ...
    def authenticate_for(self, issuer_der: bytes) -> bool: ...

class OCSPRequest:
    def __init__(self, peer_certificate: bytes, issuer_certificate: bytes) -> None: ...
    def public_bytes(self) -> bytes: ...

class BufferReadError(ValueError): ...
class BufferWriteError(ValueError): ...

class Buffer:
    def __init__(self, capacity: int = 0, data: bytes | None = None) -> None: ...
    @property
    def capacity(self) -> int: ...
    @property
    def data(self) -> bytes: ...
    def data_slice(self, start: int, end: int) -> bytes: ...
    def eof(self) -> bool: ...
    def seek(self, pos: int) -> None: ...
    def tell(self) -> int: ...
    def pull_bytes(self, length: int) -> bytes: ...
    def pull_uint8(self) -> int: ...
    def pull_uint16(self) -> int: ...
    def pull_uint24(self) -> int: ...  # only for OCSP resp parsing!
    def pull_uint32(self) -> int: ...
    def pull_uint64(self) -> int: ...
    def pull_uint_var(self) -> int: ...
    def push_bytes(self, value: bytes) -> None: ...
    def push_uint8(self, value: int) -> None: ...
    def push_uint16(self, value: int) -> None: ...
    def push_uint32(self, value: int) -> None: ...
    def push_uint64(self, value: int) -> None: ...
    def push_uint_var(self, value: int) -> None: ...

def encode_uint_var(value: int) -> bytes:
    """
    Encode a variable-length unsigned integer.
    """

def size_uint_var(value: int) -> int:
    """
    Return the number of bytes required to encode the given value
    as a QUIC variable-length unsigned integer.
    """

def idna_encode(text: str) -> bytes:
    """using UTS46"""

def idna_decode(src: bytes) -> str:
    """using UTS46"""

class RangeSet(Sequence):
    def __init__(self) -> None: ...
    def add(self, start: int, stop: int | None = None) -> None: ...
    def bounds(self) -> tuple[int, int]: ...
    def shift(self) -> tuple[int, int]: ...
    def subtract(self, start: int, stop: int) -> None: ...
    def __contains__(self, val: object) -> bool: ...
    def __eq__(self, other: Any) -> bool: ...
    def __getitem__(self, key: Any) -> tuple[int, int]: ...
    def __len__(self) -> int: ...
    def __repr__(self) -> str: ...

def decode_packet_number(truncated: int, num_bits: int, expected: int) -> int:
    """
    Recover a packet number from a truncated packet number.

    See: Appendix A - Sample Packet Number Decoding Algorithm
    """

class QuicPacketPacer:
    def __init__(self, max_datagram_size: int) -> None: ...
    def next_send_time(self, now: float) -> float | None: ...
    def update_after_send(self, now: float) -> None: ...
    def update_bucket(self, now: float) -> None: ...
    def update_rate(self, congestion_window: int, smoothed_rtt: float) -> None: ...

class QuicRttMonitor:
    """
    Roundtrip time monitor for HyStart.
    """
    def add_rtt(self, rtt: float) -> None: ...
    def is_rtt_increasing(self, rtt: float, now: float) -> bool: ...

class RevokedCertificate:
    serial_number: str
    reason: ReasonFlags
    expired_at: int

class CertificateRevocationList:
    def __init__(self, crl: bytes) -> None: ...
    def is_revoked(self, serial_number: str) -> RevokedCertificate | None: ...
    def serialize(self) -> bytes: ...
    @staticmethod
    def deserialize(src: bytes) -> CertificateRevocationList: ...
    def __len__(self) -> int: ...
    @property
    def issuer(self) -> str: ...
    @property
    def last_updated_at(self) -> int: ...
    @property
    def next_update_at(self) -> int: ...
    def authenticate_for(self, issuer_der: bytes) -> bool: ...

def rebuild_chain(leaf: bytes, intermediates: list[bytes]) -> list[bytes]: ...
def classify_certificates_der(
    certificates_der: list[bytes],
) -> tuple[list[bytes], list[bytes], list[bytes]]:
    """
    Bulk-classify a list of DER-encoded X.509 certificates into
    (trust_anchors, intermediaries, others), matching the bucketing logic
    used by qh3.tls.load_store_and_sort.  Items that fail to parse are
    silently skipped.  Each output item is the original DER bytes.
    """
    ...
