from __future__ import annotations

import ssl
from collections.abc import Mapping
from typing import Any
from typing import Callable
from typing import Type
from typing_extensions import Literal

from . import callback
from . import channel as channel_
from . import compat
from . import credentials as credentials_
from . import frame
from . import spec

PRODUCT: str

_OnHeartbeatTimeoutCallback = Callable[[Connection, int], int]
_OnCloseCallback = Callable[[Connection, Exception], None]
_OnConnectionBlockedCallback = Callable[[Connection, frame.Method[spec.Connection.Blocked]], None]
_OnConnectionUnblockedCallback = Callable[[Connection, frame.Method[spec.Connection.Unblocked]], None]
_OnOpenCallback = Callable[[Connection], None]
_OnOpenErrorCallback = Callable[[Connection, str | Exception], None]
_OnOpenChannelCallback = Callable[[channel_.Channel], None]

class Parameters:

    DEFAULT_USERNAME: str = ...
    DEFAULT_PASSWORD: str = ...

    DEFAULT_BLOCKED_CONNECTION_TIMEOUT: float | int | None = ...
    DEFAULT_CHANNEL_MAX: int = ...
    DEFAULT_CLIENT_PROPERTIES: Mapping[str, Any] | None = ...
    DEFAULT_CREDENTIALS: credentials_._VALID_TYPES = ...
    DEFAULT_CONNECTION_ATTEMPTS: Literal[1] = ...
    DEFAULT_FRAME_MAX: int = ...
    DEFAULT_HEARTBEAT_TIMEOUT: int | _OnHeartbeatTimeoutCallback | None = ...
    DEFAULT_HOST: str = ...
    DEFAULT_LOCALE: str = ...
    DEFAULT_PORT: int = ...
    DEFAULT_RETRY_DELAY: float | int = ...
    DEFAULT_SOCKET_TIMEOUT: float | int = ...
    DEFAULT_STACK_TIMEOUT: float | int = ...
    DEFAULT_SSL: bool = ...
    DEFAULT_SSL_OPTIONS: SSLOptions | None = ...
    DEFAULT_SSL_PORT: int = ...
    DEFAULT_VIRTUAL_HOST: str = ...
    DEFAULT_TCP_OPTIONS: Mapping[str, Any] | None = ...
    @property
    def blocked_connection_timeout(self) -> float | int: ...
    @blocked_connection_timeout.setter
    def blocked_connection_timeout(self, value: float | int | None) -> None: ...
    @property
    def channel_max(self) -> int: ...
    @channel_max.setter
    def channel_max(self, value: int) -> None: ...
    @property
    def client_properties(self) -> Mapping[str, Any] | None: ...
    @client_properties.setter
    def client_properties(self, value: Mapping[str, Any] | None) -> None: ...
    @property
    def connection_attempts(self) -> int: ...
    @connection_attempts.setter
    def connection_attempts(self, value: int) -> None: ...
    @property
    def credentials(self) -> credentials_._VALID_TYPES: ...
    @credentials.setter
    def credentials(self, value: credentials_._VALID_TYPES) -> None: ...
    @property
    def frame_max(self) -> int: ...
    @frame_max.setter
    def frame_max(self, value: int) -> None: ...
    @property
    def heartbeat(self) -> int | _OnHeartbeatTimeoutCallback | None: ...
    @heartbeat.setter
    def heartbeat(self, value: int | _OnHeartbeatTimeoutCallback | None) -> None: ...
    @property
    def host(self) -> str: ...
    @host.setter
    def host(self, value: str) -> None: ...
    @property
    def locale(self) -> str: ...
    @locale.setter
    def locale(self, value: str) -> str: ...
    @property
    def port(self) -> int: ...
    @port.setter
    def port(self, value: int) -> None: ...
    @property
    def retry_delay(self) -> float | int: ...
    @retry_delay.setter
    def retry_delay(self, value: float | int) -> None: ...
    @property
    def socket_timeout(self) -> float | int | None: ...
    @socket_timeout.setter
    def socket_timeout(self, value: float | int | None) -> None: ...
    @property
    def stack_timeout(self) -> float | int | None: ...
    @stack_timeout.setter
    def stack_timeout(self, value: float | int | None) -> None: ...
    @property
    def ssl_options(self) -> SSLOptions | None: ...
    @ssl_options.setter
    def ssl_options(self, value: SSLOptions | None) -> None: ...
    @property
    def virtual_host(self) -> str: ...
    @virtual_host.setter
    def virtual_host(self, value: str) -> None: ...
    @property
    def tcp_options(self) -> Mapping[str, Any] | None: ...
    @tcp_options.setter
    def tcp_options(self, value: Mapping[str, Any] | None) -> None: ...

class ConnectionParameters(Parameters):
    class _DEFAULT: ...
    def __init__(
        self,
        host: str | Type[_DEFAULT] = ...,
        port: int | Type[_DEFAULT] = ...,
        virtual_host: str | Type[_DEFAULT] = ...,
        credentials: credentials_._VALID_TYPES | Type[_DEFAULT] = ...,
        channel_max: int | Type[_DEFAULT] = ...,
        frame_max: int | Type[_DEFAULT] = ...,
        heartbeat: int | None | _OnHeartbeatTimeoutCallback | Type[_DEFAULT] = ...,
        ssl_options: SSLOptions | Type[_DEFAULT] = ...,
        connection_attempts: int | Type[_DEFAULT] = ...,
        retry_delay: float | int | Type[_DEFAULT] = ...,
        socket_timeout: float | int | Type[_DEFAULT] = ...,
        stack_timeout: float | int | Type[_DEFAULT] = ...,
        locale: str | Type[_DEFAULT] = ...,
        blocked_connection_timeout: float | int | None | Type[_DEFAULT] = ...,
        client_properties: Mapping[str, Any] | None | Type[_DEFAULT] = ...,
        tcp_options: Mapping[str, Any] | None | Type[_DEFAULT] = ...,
        **kwargs: Any,
    ) -> None: ...

class URLParameters(Parameters):
    def __init__(self, url: str) -> None: ...

class SSLOptions:

    context: ssl.SSLContext = ...
    server_hostname: str | None = ...
    def __init__(self, context: ssl.SSLContext, server_hostname: str | None = ...) -> None: ...

class Connection(compat.AbstractBase):

    ON_CONNECTION_CLOSED: str = ...
    ON_CONNECTION_ERROR: str = ...
    ON_CONNECTION_OPEN_OK: str = ...

    CONNECTION_CLOSED: int = ...
    CONNECTION_INIT: int = ...
    CONNECTION_PROTOCOL: int = ...
    CONNECTION_START: int = ...
    CONNECTION_TUNE: int = ...
    CONNECTION_OPEN: int = ...
    CONNECTION_CLOSING: int = ...

    connection_state: str | None = ...
    params: Parameters | None = ...
    callbacks: callback.CallbackManager = ...
    server_capabilities: Mapping[str, Any] | None = ...
    server_properties: dict[str, Any] | None = ...
    known_hosts: str | None = ...

    bytes_sent: int = ...
    bytes_received: int = ...
    frames_sent: int = ...
    frames_received: int = ...
    def __init__(
        self,
        parameters: Parameters | None = ...,
        on_open_callback: _OnOpenCallback | None = ...,
        on_open_error_callback: _OnOpenErrorCallback | None = ...,
        on_close_callback: _OnCloseCallback | None = ...,
        internal_connection_workflow: bool = ...,
    ) -> None: ...
    def add_on_close_callback(self, callback: _OnCloseCallback) -> None: ...
    def add_on_connection_blocked_callback(self, callback: _OnConnectionBlockedCallback) -> None: ...
    def add_on_connection_unblocked_callback(self, callback: _OnConnectionUnblockedCallback) -> None: ...
    def add_on_open_callback(self, callback: _OnOpenCallback) -> None: ...
    def add_on_open_error_callback(self, callback: _OnOpenErrorCallback, remove_default: bool = ...) -> None: ...
    def channel(
        self, channel_number: int | None = ..., on_open_callback: _OnOpenChannelCallback | None = ...
    ) -> channel_.Channel: ...
    def close(self, reply_code: int = ..., reply_text: str = ...) -> None: ...
    @property
    def is_closed(self) -> bool: ...
    @property
    def is_closing(self) -> bool: ...
    @property
    def is_open(self) -> bool: ...
    @property
    def basic_nack(self) -> bool: ...
    @property
    def consumer_cancel_notify(self) -> bool: ...
    @property
    def exchange_exchange_bindings(self) -> bool: ...
    @property
    def publisher_confirms(self) -> bool: ...
