import { type colors } from "@spacingbat3/kolor";
/**
 * The type of the activity displayed as a status message with its name (e.g.
 * *Playing \<game\>* or *Listening to \<music\>*).
 */
export declare const enum RPCActivity {
    Game = 0,
    Listening = 1,
    Streaming = 2,
    Watching = 3,
    Custom = 4,
    Competing = 5
}
/** Generic type for Discord's incoming messages format. */
export interface Message<C extends string, T extends string | never> {
    /** Message type/command. */
    cmd: C;
    /** Nonce identifying the communication. */
    nonce: string;
    /** Message arguments. */
    args: C extends "INVITE_BROWSER" | "GUILD_TEMPLATE_BROWSER" ? {
        /** An invitation code. */
        code: string;
    } : C extends "AUTHORIZE" ? {
        /** An array of OAuth2 scopes. */
        scopes: (`applications.${`builds.${"read" | "upload"}` | `commands.${"" | "permissions."}update` | "entitlements" | "store.update"}` | "bot" | "connections" | "dm_channels.read" | "email" | "gdm.join" | "guilds" | `guilds.${"join" | "members.read"}` | "identify" | `${"activities" | "messages" | "relationships" | `rpc.${"notifications" | "voice"}`}.read` | `${"activities" | `rpc.${"activities" | "voice"}`}.write` | "voice" | "webhook.incoming")[];
        /** An application's client_id. */
        client_id: string;
        /** One-time use RPC token. */
        rpc_token?: string;
        /** A username of guest account to create if the user does not have Discord. */
        username?: string;
    } : C extends "DEEP_LINK" ? {
        type: T extends string ? T : string;
        params: T extends "CHANNEL" ? {
            guildId: string;
            channelId?: string;
            search: string;
            fingerprint: string;
        } : Record<string, unknown>;
    } : C extends "SET_ACTIVITY" ? {
        /** The application's process id. */
        pid: number;
        activity: {
            /** The activity name. */
            name: string;
            /** The activity type, one of {@link RPCActivity}. */
            type: RPCActivity;
            /** A stream URL, validated only when `type` is {@link RPCActivity.Listening}. */
            url?: string;
            /** A unix timestamp (in milliseconds) of when the activity was added to the user's session. */
            created_at: number;
            /** Unix timestamps for start and/or end of the activity. */
            timestamps?: Partial<Record<"start" | "end", number>>;
            /** Application ID for the activity. */
            application_id?: number;
            /** What the user is currently doing as a part of given activity. */
            details: string;
            /** The user's current party status. */
            state?: string;
            /** An emoji used for a custom status. */
            emoji?: {
                name?: string;
                id?: number;
                animated?: string;
            };
            /** An information about the current party participating in the user's activity. */
            party?: {
                id?: number;
                size?: [current_size: number, max_size: number];
            };
            /** Images for the presence and their hover texts. */
            assets?: Partial<Record<`${"large" | "small"}_${"image" | "text"}`, string>>;
            /** Secrets for Rich Presence joining and spectating. */
            secrets?: Partial<Record<"join" | "spectate" | "match", string>>;
            /** Whether or not the activity is an instanced game session. */
            instance?: boolean;
            /**
             * An integer in range 0-511 (unsigned, 9 bits) which identifies flags.
             *
             * @summary
             *
             * Bits in number has specified flag as seen in below table:
             *
             * |  BIT | FLAG                        |
             * | ---- | --------------------------- |
             * | 1    |`INSTANCE`                   |
             * | 2    |`JOIN`                       |
             * | 3    |`SPECTATE`                   |
             * | 4    |`JOIN_REQUEST`               |
             * | 5    |`SYNC`                       |
             * | 6    |`PLAY`                       |
             * | 7    |`PARTY_PRIVACY_FRIENDS`      |
             * | 8    |`PARTY_PRIVACY_VOICE_CHANNEL`|
             * | 9    |`EMBEDDED`                   |
             */
            flags?: number;
            /** An array of buttons shown in the Rich Presence. */
            buttons?: {
                label: string;
                url: string;
            }[] & {
                length: 0 | 1 | 2;
            };
        };
    } : Record<string, unknown>;
}
/**
 * Generic response checker, assumes Discord will do requests of certain type
 * based on `cmd` and `argsType` values.
 */
export declare function isMessage<C extends string, T>(data: unknown, cmd?: C | C[], argsType?: T & string): data is Message<C, T extends string ? T : never>;
/** Verifies if given string can be parsed to `object` with `JSON.parse`. */
export declare function isJSONParsable(text: string): boolean;
/** Static response messages sent by transports. */
export declare const staticMessages: Readonly<{
    /**
     * A fake, hard-coded Discord command to spoof the presence of
     * official Discord client (which makes browser to actually start a
     * communication with the DisConnection).
     */
    readonly dispatch: {
        /** Message command. */
        readonly cmd: "DISPATCH";
        /** Message data. */
        readonly data: {
            /** Message scheme version. */
            readonly v: 1;
            /** Client properties. */
            readonly config: null;
        };
        readonly evt: "READY";
        readonly nonce: null;
    };
}>;
/**
 * Known *elements* of message payloads, which tends to be either a `code` of
 * `cmd` or `type` (for `DEEP_LINK`).
 */
export declare const knownMsgEl: Readonly<{
    codes: readonly ["INVITE_BROWSER", "GUILD_TEMPLATE_BROWSER", "AUTHORIZE", "DEEP_LINK", "SET_ACTIVITY"];
    types: readonly ["CHANNEL"];
}>;
/**
 * Flattened combination of `codes` and `types` from {@link knownMsgEl} used as
 * an array of hook names.
 */
declare const hookNames: readonly ("INVITE_BROWSER" | "GUILD_TEMPLATE_BROWSER" | "AUTHORIZE" | "SET_ACTIVITY" | "DEEP_LINK_CHANNEL")[];
/** Alias type for single element of `knownMsgEl.codes`. */
type code = typeof knownMsgEl.codes[number];
/** Alias type for single element of `knownMsgEl.types`. */
type type = typeof knownMsgEl.types[number];
/** Alias type for single hook name. */
type hookName = typeof hookNames[number];
/** An object that maps given hook names to their respective function argument tuple. */
export type HookSignatures = {
    [P in hookName]: P extends `${infer C extends "DEEP_LINK"}_${infer T extends type}` ? [request: Message<C, T>, origin: string | null] : P extends infer C extends code ? [request: Message<C, never>, origin: string | null] : never;
};
/** An alias which generates a function type from its signatures based on hook name. */
export type HookFn<T extends hookName> = (...args: HookSignatures[T]) => Promise<undefined | number>;
/**
 * An alias to list of the colors allowed to be used with `@spacingbat3/kolor`
 * library. Used for tag color in the log message.
 */
export type fgColor = Exclude<keyof typeof colors, `bg${Capitalize<keyof typeof colors>}`>;
/**
 * A specification which defines Discord communication protocol used within
 * DisConnection. It is used for implementing various *transports*, like
 * WebSocket server or UNIX socket (IPC). This class is not designed to be used
 * directly, but is meant to be extended by given transport implementation.
 */
export declare abstract class Protocol {
    #private;
    /**
     * A name which indicates the given implementation of the protocol.
     */
    abstract readonly name: string;
    /**
     * A {@link name} variant which contains all characters lowercase and contains
     * replaced whitespace characters with underscore (`_`).
     */
    get safeName(): string;
    /** A way to stop the server while {@link destroy}-ing the class structure. */
    protected abstract stopServer(): void;
    /** Writes a regular message (`log`) in the console to `stdout`. */
    log(...args: unknown[]): void;
    /** Writes an error message to `stderr`. */
    protected error(...args: unknown[]): void;
    /**
     * Writes a debug message, which will be visible whenever `NODE_DEBUG`
     * includes a `disconnection-{{@link #safeName}}`.
     */
    protected debug(...args: unknown[]): void;
    /**
     * Whenever this class has been *destroyed*.
     *
     * @see {@link destroy} for more details about this state.
     */
    isDestroyed(): boolean;
    /**
     * Removes references in class properties and methods either by replacing
     * values with a reference to the function that throws an error (for methods
     * and some required properties using getters) or sets them to a nullish value
     * (for optional properties).
     *
     * As it is hard to guarantee the Garbage Collector will ever deallocate
     * memory after dereferencing all of the objects, the goal is to prevent API
     * consumers from using class method that no longer make sense than implement
     * any kind of the memory cleanup logic.
     *
     * **Note: This operation is designed to be irreversible!** You will have to
     * initialize the new class instance if you want to use given transport again.
     *
     * @throws {@link Error} in case object has been already destroyed.
     *
     * @since v1.1.0
     */
    destroy(): void;
    /**
     * Adds a hook to the given hook list if it doesn't exist in it.
     *
     * @param {T extends HookName} name - A name of hook list.
     * @param value - A function that will be added to hook list.
     *
     * @returns number of hooks of given key or `false` if value were added before
     * @throws {@link TypeError} on invalid function parameter types.
     * @since v1.0.0
     */
    addHook<T extends hookName>(name: T, value: HookFn<T>): number | false;
    /**
     * Removes given hook function from give the hook list.
     *
     * @param name - A name of hook list.
     *
     * @returns whenever hook has been deleted
     * @throws {@link TypeError} on invalid function parameter types.
     * @since v1.0.0
     */
    removeHook<T extends hookName>(name: T, value: HookFn<T>): boolean;
    /**
     * Removes **all** hooks from the given hook list.
     *
     * @param name - A name of hook list.
     *
     * @returns if hook list wasn't empty before removing — values from it
     * @throws {@link TypeError} on invalid hook list name.
     * @since v1.0.0
     */
    removeAllHooks<T extends hookName>(name: T): boolean;
    /**
     * Lists all hooks from the given hook list.
     *
     * @param name - A name of hook list.
     *
     * @returns `Array` of hooks
     * @throws {@link TypeError} on invalid hook list name.
     * @since v1.0.0
     */
    getHooks<T extends hookName>(name: T): HookFn<T>[];
    /**
     * Whenever any of hooks will execute by server.
     *
     * @param name - A name of hook list.
     *
     * @returns whenever hooks are *active*
     * @throws {@link TypeError} on invalid hook list name.
     * @since v1.0.0
     */
    anyHooksActive<T extends hookName>(name: T): boolean;
    /**
     * Switches state of a given hook list, which can either disable it or not.
     *
     * @param name - A name of hook list.
     * @param active - New state of hooks. Defaults to negation of previous state.
     *
     * @returns current state of given hook (i.e if it is active or not)
     * @throws {@link TypeError} on invalid function parameter types.
     * @since v1.0.0
     */
    toggleHooks<T extends hookName>(name: T, active?: boolean): boolean;
    constructor(cConsole?: Console | null, color?: fgColor);
    /**
     * This method maps incoming messages from transports to outgoing messages
     * with partially-filled data, i.e. nothing is being resolved as it takes
     * place in the official Discord client.
     *
     * @param message - Incoming message from transports.
     *
     * @returns Outgoing message that can be send as a response.
     * @since v1.0.0
     */
    static messageResponse(message: Message<string, string | never>): Readonly<{
        readonly nonce: string;
        readonly evt?: null;
        readonly cmd: string;
        readonly data: {
            guildTemplate?: {
                code: {} | null;
            };
            code: {} | null;
        } | null;
    }>;
}
export {};
