import type { IConnectionManager, IMessage, IMessageConfirmation, IMessageSender, OcppRequest, OcppResponse } from '@citrineos/base';
import { AbstractMessageSender, MessageState, OcppError } from '@citrineos/base';
import type { ILogObj } from 'tslog';
import { Logger } from 'tslog';
type AnyMessage = IMessage<OcppRequest | OcppResponse | OcppError>;
/**
 * A decorator around any {@link IMessageSender} that adds resilience when the
 * underlying message broker is unavailable.
 *
 * Behaviour when the broker is **disconnected**:
 * - **Call messages** (`MessageState.Request`): a `maxCallLengthSeconds` timeout is
 *   started.  When it fires the optional {@link onCallTimeout} callback is invoked
 *   (e.g. to close the charger's WebSocket) and the pending entry is removed from
 *   memory to prevent retry accumulation.
 * - **All other messages** (`MessageState.Response` / `MessageState.Unknown`): the
 *   message is held in an in-memory buffer and replayed in order once the broker
 *   reconnects.
 *
 * Behaviour when the broker **reconnects**:
 * - All buffered non-Call messages are flushed in order through the inner sender.
 * - In-flight Call timeouts continue to run (they will still close the WS connection
 *   because the Call was never delivered to a module).
 */
export declare class BrokerAwareMessageSender extends AbstractMessageSender implements IMessageSender {
    private readonly _inner;
    private readonly _connectionManager;
    private readonly _maxCallLengthSeconds;
    /** Pending non-Call messages waiting to be flushed after reconnection. */
    private _buffer;
    /**
     * Active Call timeouts keyed by connection identifier (`tenantId:stationId`).
     * When a timeout fires the entry is deleted and `_onCallTimeout` is invoked.
     */
    private _callTimeouts;
    /**
     * Optional callback invoked when a Call times out while the broker is down.
     * Typically used to close the corresponding WebSocket connection.
     * Can be set after construction to avoid circular dependency issues.
     */
    onCallTimeout?: (stationId: string, tenantId: number) => Promise<void>;
    constructor(_inner: IMessageSender, _connectionManager: IConnectionManager, _maxCallLengthSeconds: number, logger?: Logger<ILogObj>);
    sendRequest(message: IMessage<OcppRequest>, payload?: OcppRequest): Promise<IMessageConfirmation>;
    sendResponse(message: IMessage<OcppResponse | OcppError>, payload?: OcppResponse | OcppError): Promise<IMessageConfirmation>;
    send(message: AnyMessage, payload?: OcppRequest | OcppResponse | OcppError, state?: MessageState): Promise<IMessageConfirmation>;
    shutdown(): Promise<void>;
    /**
     * Starts a `maxCallLengthSeconds` timer for a Call that cannot be delivered
     * because the broker is down.  On expiry the optional {@link onCallTimeout}
     * callback is invoked and the timeout entry is cleaned up.
     *
     * Returns `{ success: true }` so the router does not immediately send a
     * CallError – the charger will wait until the connection is closed by the timer.
     */
    private _handleDisconnectedCall;
    /** Adds a non-Call message to the in-memory buffer. */
    private _bufferMessage;
    /**
     * Replays all buffered messages through the inner sender.
     * If the broker drops again mid-flush the remaining messages are re-buffered.
     */
    private _flushBuffer;
    private _clearAllCallTimeouts;
}
export {};
