import ServerOptions from "./ServerOptions";
import { OriginsChecker } from "./OriginsChecker";
import AuthEngine from "./AuthEngine";
import Socket from "./Socket";
import EventEmitter from "emitix";
import ChannelExchange from "./ChannelExchange";
import InternalBroker from "./broker/InternalBroker";
import { HttpResponse } from "./http/EnhanceHttpResponse";
import UpgradeRequest from "./http/UpgradeRequest";
import { BatchOption, ComplexTypesOption } from "ziron-engine";
import { SkipGroupMemberOption } from "./Options";
import { HttpRequest } from "./http/EnhanceHttpRequest";
type LocalEvents<S extends Socket> = {
    'error': [Error];
    'warning': [Error];
    'badSocketAuthToken': [S, Error, string];
    'disconnection': [S, number, any];
};
type UpgradeMiddleware = (req: UpgradeRequest) => Promise<void> | void;
type SocketMiddleware<S extends Socket> = (socket: S) => Promise<void> | void;
type AuthenticateMiddleware<S extends Socket> = (socket: S, authToken: object, signedAuthToken: string) => Promise<void> | void;
type SubscribeMiddleware<S extends Socket> = (socket: S, channel: string) => Promise<void> | void;
type PublishInMiddleware<S extends Socket> = (socket: S, channel: string, data: any) => Promise<void> | void;
/**
 * @description
 * The Ziron server.
 * Mostly everything is related to web socket protocol on the server instance.
 * But an HTTP/HTTPS server is created to catch upgrade requests and to create a health endpoint.
 * All other HTTP requests will be answered with 426 (Upgrade Required),
 * but it is possible to provide a custom HTTP request handler.
 */
export default class Server<E extends {
    [key: string]: any[];
} = {}, ES extends Socket = Socket> {
    private readonly _compressionOptions;
    readonly originsChecker: OriginsChecker;
    readonly auth: AuthEngine;
    get id(): string;
    get port(): number;
    get path(): string;
    get tls(): boolean;
    private _authTokenExpireCheckerTicker;
    private _pingTicker;
    private _listenToken?;
    private _startListenPromise?;
    private readonly _groupTransport;
    protected emitter: (EventEmitter<LocalEvents<ES>> & EventEmitter<E>);
    readonly once: (EventEmitter<LocalEvents<ES>> & EventEmitter<E>)['once'];
    readonly on: (EventEmitter<LocalEvents<ES>> & EventEmitter<E>)['on'];
    readonly off: (EventEmitter<LocalEvents<ES>> & EventEmitter<E>)['off'];
    /**
     * @description
     * The connected web socket clients count.
     */
    readonly clientCount: number;
    /**
     * @description
     * The connected web socket clients.
     */
    readonly clients: Record<string, ES>;
    /**
     * @description
     * This is a counter of WebSocket messages.
     * You can reset this counter with the resetWsMessageCount method.
     */
    readonly wsMessageCount: number;
    /**
     * @description
     * This is a counter of received invoke messages.
     * You can reset this counter with the resetInvokeMessageCount method.
     */
    readonly invokeMessageCount: number;
    /**
     * @description
     * This is a counter of received transmit messages.
     * You can reset this counter with the resetTransmitMessageCount method.
     */
    readonly transmitMessageCount: number;
    /**
     * @description
     * This is a counter of HTTP messages.
     * You can reset this counter with the resetHttpMessageCount method.
     */
    readonly httpMessageCount: number;
    /**
     * @description
     * Specify a socket constructor extension.
     * This extension will be called in the socket constructor and
     * can be used to add properties to the Socket instance.
     * Use this extension only when you know what you are doing.
     * It is also recommended specifying this new Socket type at the
     * generic ES (extended socket) parameter of the Server class.
     * This approach is implemented rather than a custom Socket class to prevent
     * a larger proto chain and for the ability to add external variables into the constructor easily.
     */
    socketConstructorExtension: (socket: Socket) => void;
    /**
     * @description
     * The connection handler will be called when a new socket is connected.
     * The handler can be used to register receivers or procedures on the socket.
     * The returned value will be transmitted to the client.
     * Promises are considered, and the connection is only ready when the promise is resolved.
     */
    connectionHandler: (socket: ES) => Promise<any> | any;
    /**
     * @description
     * Set this property to handle HTTP requests.
     * Notice that firstly Ziron checks the origin and catches and processes health endpoint requests.
     * The handler will be called when the request is not answered after the Ziron pipeline.
     * If the response is still available after the Ziron pipeline and
     * the handler call Ziron responds with a 426 (Upgrade Required) response.
     */
    httpRequestHandler?: (req: HttpRequest, res: HttpResponse) => Promise<any> | any;
    /**
     * @description
     * Specify a custom health check.
     * This health check is used to process the value for the health endpoint.
     * This endpoint could be used for docker health checks.
     */
    healthCheck: () => Promise<boolean> | boolean;
    upgradeMiddleware: UpgradeMiddleware | undefined;
    socketMiddleware: SocketMiddleware<ES> | undefined;
    authenticateMiddleware: AuthenticateMiddleware<ES> | undefined;
    subscribeMiddleware: SubscribeMiddleware<ES> | undefined;
    publishInMiddleware: PublishInMiddleware<ES> | undefined;
    protected readonly internalBroker: InternalBroker;
    readonly channels: ChannelExchange;
    /**
     * @description
     * Boolean that indicates if the server should reject web socket handshakes.
     */
    refuseConnections: boolean;
    ignoreFurtherTransmits: boolean;
    ignoreFurtherInvokes: boolean;
    constructor(options?: ServerOptions);
    private _createGroupTransport;
    private _createTransportOptions;
    private _loadCompressionOptions;
    private _setUpSocketChLimit;
    private _setUpApp;
    private _startPingInterval;
    private _startAuthExpireCheck;
    private static _abortUpgrade;
    private _handleUpgrade;
    private _handleWsOpen;
    private _handleWsMessage;
    private static _handleWsDrain;
    private static _handleWsClose;
    private _setupHttpRequestHandling;
    private _processHttpHealthCheckRequest;
    /**
     * @description
     * Sends a transmit to a group.
     * Instead of channels, groups can only be accessed and controlled from the server-side and
     * messages are not shared across multiple server instances.
     * Groups don't have their own special protocol and can be used to send a standard
     * transmit optimized to multiple sockets of a group.
     * Additionally, the group transmits support batching when not using the skipMember option.
     * When using the skipMember option, the batch option will be ignored.
     * Internally prepareMultiTransmit is used to create the transmit packet,
     * so binary data is supported.
     * @param group
     * @param receiver
     * @param data
     * @param options
     */
    transmitToGroup(group: string, receiver: string, data?: any, options?: ComplexTypesOption & BatchOption & SkipGroupMemberOption): void;
    /**
     * @description
     * Returns the member count of a specific group from this server instance.
     * Instead of channels, groups can only be accessed and controlled from the server-side and
     * messages are not shared across multiple server instances.
     * Groups don't have their own special protocol and can be used to send a standard
     * transmit optimized to multiple sockets of a group.
     * Additionally, the group transmits support batching when not using the skipMember option.
     * Internally prepareMultiTransmit is used to create the transmit packet,
     * so binary data is supported.
     * @param group
     */
    getGroupMemberCount(group: string): number;
    listen(): Promise<void>;
    getInternalSubscriptions(): string[];
    resetWsMessageCount(): void;
    resetInvokeMessageCount(): void;
    resetTransmitMessageCount(): void;
    resetHttpMessageCount(): void;
    /**
     * @description
     * Resets all counts (wsMessageCount,invokeMessageCount,transmitMessageCount and httpMessageCount).
     */
    resetCounts(): void;
    stopListen(): void;
    isListening(): boolean;
    /**
     * Terminates the server.
     * After termination, you should not use this instance anymore
     * or anything else from the server.
     * [Use this method only when you know what you do.]
     */
    terminate(): void;
}
export {};
