/// <reference types="bunyan" />
/// <reference types="express" />
/// <reference types="socket.io" />
import Bunyan from "bunyan";
import * as Express from "express";
import { Store, DeepPartial, Reducer, AnyAction } from "redux";
import { Message, Client } from "@towercg2/client";
import { Server } from "../Server/index";
import { Behaviors } from "./Behaviors";
export interface ServerPluginClassBase {
    new (config: Partial<ServerPluginConfig>, server: Server): ServerPluginBase;
    readonly pluginName: string;
}
export interface ServerPluginClass<TConfig extends ServerPluginConfig, TPlugin extends ServerPluginBase> extends ServerPluginClassBase {
    new (config: Partial<TConfig>, server: Server): TPlugin;
}
export interface ServerPluginConfig {
}
export declare abstract class ServerPluginBase {
    protected readonly server: Server;
    private static readonly DEFAULT_BEHAVIORS;
    readonly name: string;
    protected readonly logger: Bunyan;
    /**
     * As opposed to configuration, which determines the runtime behavior of this plugin,
     * _behaviors_ determine immutable aspects of the plugin, such as what portions of its data
     * store are skipped when serializing to disk.
     */
    readonly behaviors: Behaviors;
    private _client;
    protected readonly client: Client;
    constructor(server: Server);
    readonly abstract state: object;
    protected buildPluginBehaviors(): Partial<Behaviors>;
    readonly dataDirectory: string;
    protected readonly abstract config: ServerPluginConfig;
    protected abstract buildDefaultConfig(): ServerPluginConfig;
    protected bindHttpEndpoints(app: Express.Application): void;
    abstract doBindHttpEndpoints(app: Express.Application): void;
    protected bindSocketIOHandlers(socket: SocketIO.Socket): void;
    abstract doBindSocketIOHandlers(socket: SocketIO.Socket): void;
    doSetClientConnection(localUri: string, clientId: string, clientSecret: string): void;
    abstract doInitialize(http: Express.Application): Promise<void>;
    abstract initialize(http: Express.Application): Promise<void>;
    abstract cleanup(): Promise<void>;
    protected eventName(eventName: string): string;
}
export declare abstract class ServerPlugin<TConfig extends ServerPluginConfig, TState extends {}> extends ServerPluginBase {
    protected readonly config: TConfig;
    protected readonly store: Store<TState>;
    constructor(config: Partial<TConfig>, server: Server);
    readonly state: TState;
    protected abstract buildDefaultConfig(): TConfig;
    protected abstract buildDefaultState(): DeepPartial<TState>;
    protected abstract buildReducer(): Reducer<TState, AnyAction>;
    doInitialize(http: Express.Application): Promise<void>;
    doBindHttpEndpoints(app: Express.Application): void;
    doBindSocketIOHandlers(socket: SocketIO.Socket): void;
    protected broadcastEvent<TEventType extends string, TPayload extends object, TEvent extends Message<TEventType, TPayload>>(event: TEvent): void;
    protected handleMessage<TMessageType extends string, TPayload extends object>(messageType: TMessageType, client: SocketIO.Socket, fn: (payload: TPayload, sender: SocketIO.Socket) => Promise<any>): void;
    protected handleRequest<TRequestType extends string, TPayload extends object, TData extends object>(requestType: TRequestType, client: SocketIO.Socket, fn: (payload: TPayload, sender: SocketIO.Socket) => Promise<TData>): void;
}
