import { connect, Connection, Channel } from 'amqplib';
import { Logger } from '../log/LogManager';
import { ReadyGate } from '../util/ReadyGate';
import { RabbitmqClientConfig } from './RabbitmqConfig';
export declare enum ShutdownMessage {
    ECONNRESET = "read ECONNRESET",
    HEARTBEATTIMEOUT = "Heartbeat timeout"
}
export interface MessageHeader {
    retriesCount: 0;
}
export interface PublishOptions {
    expiration?: string | number;
    userId?: string;
    CC?: string | string[];
    mandatory?: boolean;
    persistent?: boolean;
    deliveryMode?: boolean | number;
    BCC?: string | string[];
    contentType?: string;
    contentEncoding?: string;
    headers?: any | MessageHeader;
    priority?: number;
    correlationId?: string;
    replyTo?: string;
    messageId?: string;
    timestamp?: number;
    type?: string;
    appId?: string;
}
export interface ConsumeOptions {
    consumerTag?: string;
    noLocal?: boolean;
    noAck?: boolean;
    exclusive?: boolean;
    priority?: number;
    arguments?: any;
}
export interface RepliesConsume {
    consumerTag: string;
}
export declare enum ClientPropertyTag {
    Connection = "connection",
    Channel = "channel"
}
export declare abstract class RabbitmqClient {
    protected channel: Channel;
    protected connection: Connection;
    protected logger: Logger;
    protected clientConfig: RabbitmqClientConfig;
    protected name: string;
    /**
     * Whether the connection should be closed. This is not a statud indicator that show whether the connection is closed.
     * It is a flag that indicates whether the client has been purposely closed by code, as opposed to being closed because of an error.
     */
    protected closed: boolean;
    protected reconnecting: boolean;
    protected readyGate: ReadyGate;
    protected shutdownFunction: () => void;
    protected connectFunction: typeof connect;
    constructor(clientConfig: RabbitmqClientConfig, name: string);
    init(addHandler?: boolean): Promise<void>;
    /**
     * Connect to RabbitMQ broker
     */
    protected connect(addHandler?: boolean): Promise<void>;
    private createConnection;
    protected addConnectionHandlers(): void;
    protected createChannel(addHandler: boolean): Promise<void>;
    protected addChannelHandlers(): void;
    /**
     * 1. Reconnect when errors occur.
     * 2. Errors do not exist if connection.close() is called
     *  or a server initiated graceful close.
     * 3. Graceful closed connection will be recovered.
     * 4. Because close event with an error will be emitted after connection error event,
     *  only handle connection close event.
     * @param err
     */
    protected handleConnectionClose(err?: Error): Promise<void>;
    /**
     * Schedule reconnection in error handler because connection errors do not always trigger a 'close' event.
     * A channel error event is emitted if a server closes the channel for any reason.
     * A channel will not emit 'error' if its connection closes with an error.
     *
     * Channel Errors are triggered by one of the following:
     *  1. failed to consume.
     *
     * Channel error event will trigger connection error event which will
     * trigger connection close event. Do not handle connection error event because a close event with error will be emiited.
     * Then the close event will be handled.
     */
    protected handleError(emitter: ClientPropertyTag, err: any): Promise<void>;
    /**
     * Handle when a channel is closed gracefully.
     */
    protected handleChannelClose(err: Error): void;
    protected closeAllAndScheduleReconnection(): Promise<boolean>;
    backoffWait(tryNum: number): Promise<void>;
    attemptReconnection(): Promise<boolean>;
    close(): Promise<void>;
    private closeChannel;
    private closeConnection;
    protected debugMsg(str: any): string;
    protected defaultHeader(): MessageHeader;
    private stopReconnecting;
    private startReconnecting;
}
