/// <reference types="node" />
import { EventEmitter } from "events";
import { ConnectionInstance, InstanceDisconnectReason } from "./ConnectionInstance";
import { ClientEvents } from "matrix-org-irc";
import { IrcRoom } from "../models/IrcRoom";
import { IrcServer } from "./IrcServer";
import { IrcClientConfig } from "../models/IrcClientConfig";
import { MatrixUser } from "matrix-appservice-bridge";
import { IrcAction } from "../models/IrcAction";
import { IdentGenerator } from "./IdentGenerator";
import { Ipv6Generator } from "./Ipv6Generator";
import { IrcEventBroker } from "./IrcEventBroker";
import { Client } from "matrix-org-irc";
import { IrcPoolClient } from "../pool-service/IrcPoolClient";
export interface GetNicksResponse {
    server: IrcServer;
    channel: string;
    names: Map<string, string>;
}
export interface GetNicksResponseOperators extends GetNicksResponse {
    operatorNicks: string[];
}
export interface BridgedClientLogger {
    debug(msg: string, ...args: any[]): void;
    info(msg: string, ...args: any[]): void;
    error(msg: string, ...args: any[]): void;
}
export declare const illegalCharactersRegex: RegExp;
export declare enum BridgedClientStatus {
    CREATED = 0,
    CONNECTING = 1,
    CONNECTED = 2,
    DEAD = 3,
    KILLED = 4
}
interface NotConnected {
    status: BridgedClientStatus.CREATED | BridgedClientStatus.CONNECTING | BridgedClientStatus.DEAD | BridgedClientStatus.KILLED;
}
interface Connected {
    status: BridgedClientStatus.CONNECTED;
    client: Client;
    inst: ConnectionInstance;
}
type State = Connected | NotConnected;
export declare class BridgedClient extends EventEmitter {
    readonly server: IrcServer;
    private clientConfig;
    readonly matrixUser: MatrixUser | undefined;
    readonly isBot: boolean;
    private readonly eventBroker;
    private readonly identGenerator;
    private readonly ipv6Generator;
    private readonly redisPool?;
    private readonly encodingFallback?;
    readonly userId: string | null;
    displayName: string | null;
    private _nick;
    readonly id: string;
    private readonly password?;
    private lastActionTs;
    private _explicitDisconnect;
    private _disconnectReason;
    private channelJoinDefers;
    private _chanList;
    private connectDefer;
    readonly log: BridgedClientLogger;
    private cachedOperatorNicksInfo;
    private idleTimeout;
    private whoisPendingNicks;
    private state;
    /**
     * Create a new bridged IRC client.
     * @constructor
     * @param {IrcServer} server
     * @param {IrcClientConfig} ircClientConfig : The IRC user to create a connection for.
     * @param {MatrixUser} matrixUser : Optional. The matrix user representing this virtual IRC user.
     * @param {boolean} isBot : True if this is the bot
     * @param {IrcEventBroker} eventBroker
     * @param {IdentGenerator} identGenerator
     * @param {Ipv6Generator} ipv6Generator
     */
    constructor(server: IrcServer, clientConfig: IrcClientConfig, matrixUser: MatrixUser | undefined, isBot: boolean, eventBroker: IrcEventBroker, identGenerator: IdentGenerator, ipv6Generator: Ipv6Generator, redisPool?: IrcPoolClient | undefined, encodingFallback?: string | undefined);
    get explicitDisconnect(): boolean;
    get disconnectReason(): string | null;
    get chanList(): Set<string>;
    get status(): BridgedClientStatus;
    get nick(): string;
    getClientConfig(): IrcClientConfig;
    kill(reason?: string): Promise<void>;
    isDead(): boolean;
    toString(): string;
    /**
     * @return {ConnectionInstance} A new connected connection instance.
     */
    connect(): Promise<ConnectionInstance>;
    reconnect(reconnectChanList: string[]): Promise<void>;
    disconnect(reason: InstanceDisconnectReason, textReason?: string, explicit?: boolean): Promise<void>;
    private disconnectWithState;
    /**
     * Determines if a nick name already exists.
     */
    checkNickExists(nick: string): Promise<boolean>;
    /**
     * Change this user's nick.
     * @param {string} newNick The new nick for the user.
     * @param {boolean} throwOnInvalid True to throw an error on invalid nicks
     * instead of coercing them.
     * @return {Promise<String>} Which resolves to a message to be sent to the user.
     */
    changeNick(newNick: string, throwOnInvalid: boolean): Promise<string>;
    private sendNickCommand;
    leaveChannel(channel: string, reason?: string): Promise<void>;
    inChannel(channel: string): boolean;
    kick(nick: string, channel: string, reason: string): Promise<void>;
    sendAction(room: IrcRoom, action: IrcAction): Promise<void>;
    /**
     * Get the whois info for an IRC user
     * @param {string} nick : The nick to call /whois on
     */
    whois(nick: string): Promise<{
        server: IrcServer;
        nick: string;
        msg: string;
    } | null>;
    /**
     * Get the operators of a channel (including users more powerful than operators)
     * @param {string} channel : The channel to call /names on
     * @param {object} opts: Optional. An object containing the following key-value pairs:
     *     @param {string} key : Optional. The key to use to join the channel.
     *     @param {integer} cacheDurationMs : Optional. The duration of time to keep a
     *         list of operator nicks cached. If > 0, the operator nicks will be returned
     *         whilst the cache is still valid and it will become invalid after cacheDurationMs
     *         milliseconds. Cache will not be used if left undefined.
     */
    getOperators(channel: string, opts?: {
        key?: string;
        cacheDurationMs?: number;
    }): Promise<GetNicksResponseOperators>;
    /**
     * Get the nicks of the users in a channel
     * @param {string} channel : The channel to call /names on
     */
    getNicks(channel: string): Promise<GetNicksResponse>;
    /**
     * Convert the given nick into a valid nick. This involves length and character
     * checks on the provided nick. If the client is connected to an IRCd then the
     * cmds received (e.g. NICKLEN) will be used in the calculations. If the client
     * is NOT connected to an IRCd then this function will NOT take length checks
     * into account. This means this function will optimistically allow long nicks
     * in the hopes that it will succeed, rather than use the RFC stated maximum of
     * 9 characters which is far too small. In testing, IRCds coerce long
     * nicks up to the limit rather than preventing the connection entirely.
     *
     * This function may modify the nick in interesting ways in order to coerce the
     * given nick into a valid nick. If throwOnInvalid is true, this function will
     * throw a human-readable error instead of coercing the nick on invalid nicks.
     *
     * @param {string} nick The nick to convert into a valid nick.
     * @param {boolean} throwOnInvalid True to throw an error on invalid nicks
     * instead of coercing them.
     * @return {string} A valid nick.
     * @throws Only if throwOnInvalid is true and the nick is not a valid nick.
     * The error message will contain a human-readable message which can be sent
     * back to a user.
     */
    static getValidNick(nick: string, throwOnInvalid: boolean, state: State): string;
    private keepAlive;
    private removeChannel;
    private addChannel;
    getLastActionTs(): number;
    private onConnectionCreated;
    private setTopic;
    private sendMessage;
    joinChannel(channel: string, key?: string, attemptCount?: number): Promise<IrcRoom>;
    private _joinChannel;
    getMaxLineLength(): number;
    getSplitMessages(target: string, text: string): string[];
    getClientInternalNick(): string;
    mode(channelOrNick: string): Promise<void>;
    sendCommands(...data: string[]): Promise<void>;
    writeToConnection(buffer: string): void;
    addClientListener<T extends keyof ClientEvents>(type: T, listener: ClientEvents[T]): void;
    removeClientListener(type: keyof ClientEvents, listener: (msg: unknown) => void): void;
    caseFold(channel: string): string;
    modeForPrefix(prefix: string): string | null;
    isUserPrefixMorePowerfulThan(prefix: string, testPrefix: string): boolean | null;
    chanData(channel: string): import("matrix-org-irc").ChanData | undefined;
    waitForConnected(): Promise<void>;
    assertConnected(): Client;
}
export {};
