import EventEmitter from 'node:events';
import { Cmd, MethodParams, Envelope, MessageBody, ReturnedMessage, SyncMessage } from './codec';
import { Channel } from './Channel';
import { ConnectionOptions } from './normalize';
import { Consumer, ConsumerProps, ConsumerHandler } from './Consumer';
import { RPCClient, RPCProps } from './RPCClient';
export declare interface Connection {
    /** The connection is successfully (re)established */
    on(name: 'connection', cb: () => void): this;
    /** The rabbitmq server is low on resources. Message publishers should pause.
     * The outbound side of the TCP socket is blocked until
     * "connection.unblocked" is received, meaning messages will be held in
     * memory.
     * {@link https://www.rabbitmq.com/connection-blocked.html}
     * {@label BLOCKED} */
    on(name: 'connection.blocked', cb: (reason: string) => void): this;
    /** The rabbitmq server is accepting new messages. */
    on(name: 'connection.unblocked', cb: () => void): this;
    on(name: 'error', cb: (err: any) => void): this;
}
/**
 * This represents a single connection to a RabbitMQ server (or cluster). Once
 * created, it will immediately attempt to establish a connection. When the
 * connection is lost, for whatever reason, it will reconnect. This implements
 * the EventEmitter interface and may emit `error` events. Close it with
 * {@link Connection#close | Connection#close()}
 *
 * @example
 * ```
 * const rabbit = new Connection('amqp://guest:guest@localhost:5672')
 * rabbit.on('error', (err) => {
 *   console.log('RabbitMQ connection error', err)
 * })
 * rabbit.on('connection', () => {
 *   console.log('RabbitMQ (re)connected')
 * })
 * process.on('SIGINT', () => {
 *   rabbit.close()
 * })
 * ```
 */
export declare class Connection extends EventEmitter {
    constructor(propsOrUrl?: string | ConnectionOptions);
    /**
     * Allocate and return a new AMQP Channel. You MUST close the channel
     * yourself. Will wait for connect/reconnect when necessary.
     */
    acquire(): Promise<Channel>;
    /**
     * Wait for channels to close and then end the connection. Will not
     * automatically close any channels, giving you the chance to ack/nack any
     * outstanding messages while preventing new channels.
     */
    close(): Promise<void>;
    /** Immediately destroy the connection. All channels are closed. All pending
     * actions are rejected. */
    unsafeDestroy(): void;
    /** Create a message consumer that can recover from dropped connections.
     * @param cb Process an incoming message. */
    createConsumer(props: ConsumerProps, cb: ConsumerHandler): Consumer;
    /** This will create a single "client" `Channel` on which you may publish
     * messages and listen for direct responses. This can allow, for example, two
     * micro-services to communicate with each other using RabbitMQ as the
     * middleman instead of directly via HTTP. */
    createRPCClient(props?: RPCProps): RPCClient;
    /**
     * Create a message publisher that can recover from dropped connections.
     * This will create a dedicated Channel, declare queues, declare exchanges,
     * and declare bindings. If the connection is reset, then all of this setup
     * will rerun on a new Channel. This also supports retries.
     */
    createPublisher(props?: PublisherProps): Publisher;
    /** {@inheritDoc Channel#basicGet} */
    basicGet(params: MethodParams[Cmd.BasicGet]): Promise<undefined | SyncMessage>;
    basicGet(queue?: string): Promise<undefined | SyncMessage>;
    /** @ignore */
    basicGet(params?: string | MethodParams[Cmd.BasicGet]): Promise<undefined | SyncMessage>;
    /** {@inheritDoc Channel#queueDeclare} */
    queueDeclare(params: MethodParams[Cmd.QueueDeclare]): Promise<MethodParams[Cmd.QueueDeclareOK]>;
    queueDeclare(queue?: string): Promise<MethodParams[Cmd.QueueDeclareOK]>;
    /** @ignore */
    queueDeclare(params?: string | MethodParams[Cmd.QueueDeclare]): Promise<MethodParams[Cmd.QueueDeclareOK]>;
    /** {@inheritDoc Channel#exchangeBind} */
    exchangeBind(params: MethodParams[Cmd.ExchangeBind]): Promise<void>;
    /** {@inheritDoc Channel#exchangeDeclare} */
    exchangeDeclare(params: MethodParams[Cmd.ExchangeDeclare]): Promise<void>;
    /** {@inheritDoc Channel#exchangeDelete} */
    exchangeDelete(params: MethodParams[Cmd.ExchangeDelete]): Promise<void>;
    /** {@inheritDoc Channel#exchangeUnbind} */
    exchangeUnbind(params: MethodParams[Cmd.ExchangeUnbind]): Promise<void>;
    /** {@inheritDoc Channel#queueBind} */
    queueBind(params: MethodParams[Cmd.QueueBind]): Promise<void>;
    /** {@inheritDoc Channel#queueDelete} */
    queueDelete(params: MethodParams[Cmd.QueueDelete]): Promise<MethodParams[Cmd.QueueDeleteOK]>;
    queueDelete(queue?: string): Promise<MethodParams[Cmd.QueueDeleteOK]>;
    /** @ignore */
    queueDelete(params?: string | MethodParams[Cmd.QueueDelete]): Promise<MethodParams[Cmd.QueueDeleteOK]>;
    /** {@inheritDoc Channel#queuePurge} */
    queuePurge(queue?: string): Promise<MethodParams[Cmd.QueuePurgeOK]>;
    queuePurge(params: MethodParams[Cmd.QueuePurge]): Promise<MethodParams[Cmd.QueuePurgeOK]>;
    /** @ignore */
    queuePurge(params?: string | MethodParams[Cmd.QueuePurge]): Promise<MethodParams[Cmd.QueuePurgeOK]>;
    /** {@inheritDoc Channel#queueUnbind} */
    queueUnbind(params: MethodParams[Cmd.QueueUnbind]): Promise<void>;
    /** True if the connection is established and unblocked. See also {@link Connection#on:BLOCKED | Connection#on('connection.blocked')}) */
    get ready(): boolean;
    /**
     * Returns a promise which is resolved when the connection is established.
     * WARNING: if timeout=0 and you call close() before the client can connect,
     * then this promise may never resolve!
     * @param timeout Milliseconds to wait before giving up and rejecting the
     * promise. Use 0 for no timeout.
     * @param disableAutoClose By default this will automatically call
     * `connection.close()` when the timeout is reached. If
     * disableAutoClose=true, then connection will instead continue to retry
     * after this promise is rejected. You can call `close()` manually.
    **/
    onConnect(timeout?: number, disableAutoClose?: boolean): Promise<void>;
}
export interface PublisherProps {
    /** Enable publish-confirm mode. See {@link Channel#confirmSelect} */
    confirm?: boolean;
    /** Maximum publish attempts. Retries are disabled by default.
     * Increase this number to retry when a publish fails. The Connection options
     * acquireTimeout, retryLow, and retryHigh will affect time between retries.
     * Each failed attempt will also emit a "retry" event.
     * @default 1
     * */
    maxAttempts?: number;
    /** see {@link Channel.on}('basic.return') */
    onReturn?: (msg: ReturnedMessage) => void;
    /**
     * Define any queues to be declared before the first publish and whenever
     * the connection is reset. Same as {@link Channel#queueDeclare | Channel#queueDeclare()}
     */
    queues?: Array<MethodParams[Cmd.QueueDeclare]>;
    /**
     * Define any exchanges to be declared before the first publish and
     * whenever the connection is reset. Same as {@link Channel#exchangeDeclare | Channel#exchangeDeclare()}
     */
    exchanges?: Array<MethodParams[Cmd.ExchangeDeclare]>;
    /**
     * Define any queue-exchange bindings to be declared before the first publish and
     * whenever the connection is reset. Same as {@link Channel#queueBind | Channel#queueBind()}
     */
    queueBindings?: Array<MethodParams[Cmd.QueueBind]>;
    /**
     * Define any exchange-exchange bindings to be declared before the first publish and
     * whenever the connection is reset. Same as {@link Channel#exchangeBind | Channel#exchangeBind()}
     */
    exchangeBindings?: Array<MethodParams[Cmd.ExchangeBind]>;
}
/**
 * @see {@link Connection#createPublisher | Connection#createPublisher()}
 *
 * The underlying Channel is lazily created the first time a message is
 * published.
 *
 * @example
 * ```
 * const pub = rabbit.createPublisher({
 *   confirm: true,
 *   exchanges: [{exchange: 'user', type: 'topic'}]
 * })
 *
 * await pub.send({exchange: 'user', routingKey: 'user.create'}, userInfo)
 *
 * await pub.close()
 * ```
 */
export interface Publisher extends EventEmitter {
    /** {@inheritDoc Channel#basicPublish} */
    send(envelope: Envelope, body: MessageBody): Promise<void>;
    /** Send directly to a queue. Same as `send({routingKey: queue}, body)` */
    send(queue: string, body: MessageBody): Promise<void>;
    /** @ignore */
    send(envelope: string | Envelope, body: MessageBody): Promise<void>;
    /** {@inheritDoc Channel#on:BASIC_RETURN} */
    on(name: 'basic.return', cb: (msg: ReturnedMessage) => void): this;
    /** See maxAttempts. Emitted each time a failed publish will be retried. */
    on(name: 'retry', cb: (err: any, envelope: Envelope, body: MessageBody) => void): this;
    /** Close the underlying channel */
    close(): Promise<void>;
}
