import { Deferred, Deque, LruMap, LruSet, timers } from '@fuman/utils';
import { TlBinaryWriter, TlReaderMap, TlWriterMap } from '@mtcute/tl-runtime';
import { mtp, tl } from '../tl/index.js';
import { ICryptoProvider, Logger, LongMap, SortedArray } from '../utils/index.js';
import { ServerSaltManager } from './server-salt.js';
import { default as Long } from 'long';
import { AuthKey } from './auth-key.js';
export interface PendingRpc {
    method: string;
    data: Uint8Array;
    promise: Deferred<unknown>;
    stack?: string;
    gzipOverhead?: number;
    chainId?: string | number;
    invokeAfter?: Long;
    sent?: boolean;
    done?: boolean;
    msgId?: Long;
    seqNo?: number;
    containerId?: Long;
    acked?: boolean;
    initConn?: boolean;
    getState?: number;
    cancelled?: boolean;
    timeout?: timers.Timer;
    resetAbortSignal?: () => void;
}
export type PendingMessage = {
    _: 'rpc';
    rpc: PendingRpc;
} | {
    _: 'container';
    msgIds: Long[];
} | {
    _: 'state';
    msgIds: Long[];
    containerId: Long;
} | {
    _: 'resend';
    msgIds: Long[];
    containerId: Long;
} | {
    _: 'ping';
    pingId: Long;
    containerId: Long;
} | {
    _: 'destroy_session';
    sessionId: Long;
    containerId: Long;
} | {
    _: 'cancel';
    msgId: Long;
    containerId: Long;
} | {
    _: 'future_salts';
    containerId: Long;
} | {
    _: 'bind';
    promise: Deferred<boolean | mtp.RawMt_rpc_error>;
};
/**
 * Class encapsulating a single MTProto session and storing
 * all the relevant state
 */
export declare class MtprotoSession {
    readonly _crypto: ICryptoProvider;
    readonly log: Logger;
    readonly _readerMap: TlReaderMap;
    readonly _writerMap: TlWriterMap;
    readonly _salts: ServerSaltManager;
    _sessionId: Long;
    _authKey: AuthKey;
    _authKeyTemp: AuthKey;
    _authKeyTempSecondary: AuthKey;
    _timeOffset: number;
    _lastMessageId: Long;
    _seqNo: number;
    recentOutgoingMsgIds: LruSet<Long>;
    recentIncomingMsgIds: LruSet<Long>;
    recentStateRequests: LruMap<Long, Long[]>;
    queuedRpc: Deque<PendingRpc>;
    queuedAcks: Long[];
    queuedStateReq: Long[];
    queuedResendReq: Long[];
    queuedCancelReq: Long[];
    getStateSchedule: SortedArray<PendingRpc>;
    pendingGetStateTimeouts: LongMap<timers.Timer>;
    chains: Map<string | number, Long>;
    chainsPendingFails: Map<string | number, SortedArray<PendingRpc>>;
    pendingMessages: LongMap<PendingMessage>;
    lastPingRtt: number;
    lastPingTime: number;
    lastPingMsgId: Long;
    lastSessionCreatedUid: Long;
    initConnectionCalled: boolean;
    authorizationPending: boolean;
    next429Timeout: number;
    current429Timeout?: timers.Timer;
    next429ResetTimeout?: timers.Timer;
    constructor(_crypto: ICryptoProvider, log: Logger, _readerMap: TlReaderMap, _writerMap: TlWriterMap, _salts: ServerSaltManager);
    get hasPendingMessages(): boolean;
    /**
     * Reset session by resetting auth key(s) and session state
     */
    reset(withAuthKey?: boolean): void;
    resetAuthKey(): void;
    updateTimeOffset(offset: number): void;
    /**
     * Reset session state and generate a new session ID.
     *
     * By default, also cancels any pending RPC requests.
     * If `keepPending` is set to `true`, pending requests will be kept
     */
    resetState(keepPending?: boolean): void;
    enqueueRpc(rpc: PendingRpc, force?: boolean): boolean;
    getMessageId(): Long;
    getSeqNo(isContentRelated?: boolean): number;
    /** Encrypt a single MTProto message using session's keys */
    encryptMessage(message: Uint8Array): Uint8Array;
    /** Decrypt a single MTProto message using session's keys */
    decryptMessage(data: Uint8Array, callback: Parameters<AuthKey['decryptMessage']>[2]): void;
    writeMessage(writer: TlBinaryWriter, content: tl.TlObject | mtp.TlObject | Uint8Array, isContentRelated?: boolean): Long;
    onTransportFlood(callback: () => void): void;
    resetLastPing(withTime?: boolean): void;
    addToChain(chainId: string | number, msgId: Long): Long | undefined;
    removeFromChain(chainId: string | number, msgId: Long): void;
    getPendingChainedFails(chainId: string | number): SortedArray<PendingRpc>;
}
