import { ReconnectionStrategy } from '@fuman/net';
import { TlReaderMap, TlWriterMap } from '@mtcute/tl-runtime';
import { IMtStorageProvider } from '../storage/provider.js';
import { StorageManagerExtraOptions, StorageManager } from '../storage/storage.js';
import { mtp, tl } from '../tl/index.js';
import { MustEqual } from '../types/index.js';
import { ICorePlatform } from '../types/platform.js';
import { DcOptions, ICryptoProvider, Logger } from '../utils/index.js';
import { NetworkManagerExtraParams, RpcCallOptions, NetworkManager } from './network-manager.js';
import { TelegramTransport } from './transports/abstract.js';
import { Emitter } from '@fuman/utils';
import { ConfigManager } from './config-manager.js';
/** Options for {@link MtClient} */
export interface MtClientOptions {
    /**
     * API ID from my.telegram.org
     */
    apiId: number;
    /**
     * API hash from my.telegram.org
     */
    apiHash: string;
    /**
     * Storage to use for this client.
     */
    storage: IMtStorageProvider;
    /** Additional options for the storage manager */
    storageOptions?: StorageManagerExtraOptions;
    /**
     * Cryptography provider to allow delegating
     * crypto to native addon, worker, etc.
     */
    crypto: ICryptoProvider;
    platform: ICorePlatform;
    /**
     * Whether to use IPv6 datacenters
     * (IPv6 will be preferred when choosing a DC by id)
     * (default: false)
     */
    useIpv6?: boolean;
    /**
     * Primary DC to use for initial connection.
     * This does not mean this will be the only DC used,
     * nor that this DC will actually be primary, this only
     * determines the first DC the library will try to connect to.
     * Can be used to connect to other networks (like test DCs).
     *
     * When session already contains primary DC, this parameter is ignored.
     *
     * @default  Production DC 2.
     */
    defaultDcs?: DcOptions;
    /**
     * Whether to connect to test servers.
     *
     * If passed, {@link defaultDc} defaults to Test DC 2.
     *
     * **Must** be passed if using test servers, even if
     * you passed custom {@link defaultDc}
     */
    testMode?: boolean;
    /**
     * Additional options for initConnection call.
     * `apiId` and `query` are not available and will be ignored.
     * Omitted values will be filled with defaults
     */
    initConnectionOptions?: Partial<Omit<tl.RawInitConnectionRequest, 'apiId' | 'query'>>;
    /**
     * Transport to use in the client.
     *
     * @default  platform-specific transport: WebSocket on the web, TCP in node
     */
    transport: TelegramTransport;
    /**
     * Reconnection strategy.
     *
     * @default  simple reconnection strategy: first 0ms, then up to 5s (increasing by 1s)
     */
    reconnectionStrategy?: ReconnectionStrategy;
    /**
     * If true, all API calls will be wrapped with `tl.invokeWithoutUpdates`,
     * effectively disabling the server-sent events for the clients.
     * May be useful in some cases.
     *
     * @default false
     */
    disableUpdates?: boolean;
    /**
     * Extra parameters for {@link NetworkManager}
     */
    network?: NetworkManagerExtraParams;
    /**
     * Logger instance for the client.
     * If not passed, a new one will be created.
     */
    logger?: Logger;
    /**
     * Set logging level for the client.
     * Shorthand for `client.log.level = level`.
     *
     * See static members of {@link LogManager} for possible values.
     */
    logLevel?: number;
    /**
     * **EXPERT USE ONLY!**
     *
     * Override TL layer used for the connection.
     *
     * **Does not** change the schema used.
     */
    overrideLayer?: number;
    /**
     * **EXPERT USE ONLY**
     *
     * Override reader map used for the connection.
     */
    readerMap?: TlReaderMap;
    /**
     * **EXPERT USE ONLY**
     *
     * Override writer map used for the connection.
     */
    writerMap?: TlWriterMap;
}
/**
 * Basic MTProto client implementation, only doing the bare minimum
 * to make RPC calls and receive low-level updates, as well as providing
 * some APIs to manage that.
 */
export declare class MtClient {
    readonly params: MtClientOptions & {
        onError: (err: unknown) => void;
    };
    /**
     * Crypto provider taken from {@link MtClientOptions.crypto}
     */
    readonly crypto: ICryptoProvider;
    /** Storage manager */
    readonly storage: StorageManager;
    /**
     * "Test mode" taken from {@link MtClientOptions.testMode}
     */
    protected readonly _testMode: boolean;
    /**
     * Primary DCs taken from {@link MtClientOptions.defaultDcs},
     * loaded from session or changed by other means (like redirecting).
     */
    _defaultDcs: DcOptions;
    /** TL layer used by the client */
    readonly _layer: number;
    /** TL readers map used by the client */
    readonly _readerMap: TlReaderMap;
    /** TL writers map used by the client */
    readonly _writerMap: TlWriterMap;
    readonly _config: ConfigManager;
    readonly log: Logger;
    readonly network: NetworkManager;
    private _abortController;
    readonly stopSignal: AbortSignal;
    readonly onUsable: Emitter<void>;
    readonly onConnecting: Emitter<void>;
    readonly onNetworkChanged: Emitter<boolean>;
    readonly onUpdate: Emitter<tl.TypeUpdates>;
    constructor(params: MtClientOptions & {
        onError: (err: unknown) => void;
    });
    private _prepare;
    /**
     * **ADVANCED**
     *
     * Do all the preparations, but don't connect just yet.
     * Useful when you want to do some preparations before
     * connecting, like setting up session.
     *
     * Call {@link connect} to actually connect.
     */
    prepare(): Promise<void>;
    private _connect;
    /**
     * Initialize the connection to the primary DC.
     *
     * You shouldn't usually call this method directly as it is called
     * implicitly the first time you call {@link call}.
     */
    connect(): Promise<void>;
    disconnect(): Promise<void>;
    /**
     * Close all connections and finalize the client.
     *
     * **Note**: must be called *after* {@link disconnect}
     */
    destroy(): Promise<void>;
    /**
     * Make an RPC call.
     *
     * The connection must have been {@link connect}-ed
     * before calling this method.
     *
     * This method is still quite low-level and you shouldn't use this
     * when using high-level API provided by `@mtcute/client`.
     *
     * @param message  RPC method to call
     * @param params  Additional call parameters
     */
    call<T extends tl.RpcMethod>(message: MustEqual<T, tl.RpcMethod>, params?: RpcCallOptions): Promise<tl.RpcCallReturn[T['_']] | mtp.RawMt_rpc_error>;
}
