import { Deferred } from "./util";
import { AssetEvent, AttributeEvent, AttributeRef, EventSubscription, SharedEvent } from "@openremote/model";
export declare enum EventProviderStatus {
    DISCONNECTED = "DISCONNECTED",
    CONNECTED = "CONNECTED",
    CONNECTING = "CONNECTING"
}
export interface EventProvider {
    status: EventProviderStatus;
    connect(): Promise<boolean>;
    disconnect(): void;
    subscribeStatusChange(callback: (status: EventProviderStatus) => void): void;
    unsubscribeStatusChange(callback: (status: EventProviderStatus) => void): void;
    subscribe<T extends SharedEvent>(eventSubscription: EventSubscription<T>, callback: (event: T) => void): Promise<string>;
    unsubscribe<T extends SharedEvent>(subscriptionId: string): void;
    /**
     * Subscribe to {@link AssetEvent}s for the specified {@link Asset}s for all {@link Asset}s
     */
    subscribeAssetEvents(ids: string[] | AttributeRef[] | undefined, requestCurrentValues: boolean, callback: (event: AssetEvent) => void): Promise<string>;
    /**
     * Subscribe to {@link AttributeEvent}s for the specified {@link Asset}s and if {@link AttributeRef}s are provided
     * then the attribute names from the refs will be used for each asset ID.
     */
    subscribeAttributeEvents(ids: string[] | AttributeRef[], requestCurrentValues: boolean, callback: (event: AttributeEvent) => void): Promise<string>;
    sendEvent<T extends SharedEvent>(event: T): void;
    sendEventWithReply<T extends SharedEvent, U extends SharedEvent>(event: T): Promise<U>;
}
export interface EventProviderFactory {
    getEventProvider(): EventProvider | undefined;
}
interface EventSubscriptionInfo<T extends SharedEvent> {
    eventSubscription: EventSubscription<T>;
    callback: (event: T) => void;
    deferred: Deferred<string> | null;
}
declare abstract class EventProviderImpl implements EventProvider {
    protected static MIN_RECONNECT_DELAY: number;
    protected static MAX_RECONNECT_DELAY: number;
    protected _disconnectRequested: boolean;
    protected _reconnectDelayMillis: number;
    protected _reconnectTimer: number | null;
    protected _status: EventProviderStatus;
    protected _connectingDeferred: Deferred<boolean> | null;
    protected _statusCallbacks: Array<(status: EventProviderStatus) => void>;
    protected _pendingSubscription: EventSubscriptionInfo<SharedEvent> | null;
    protected _queuedSubscriptions: EventSubscriptionInfo<SharedEvent>[];
    protected _subscriptionMap: Map<string, EventSubscriptionInfo<SharedEvent>>;
    protected _assetEventPromise?: Promise<string>;
    protected _assetEventCallbackMap: Map<string, (e: AssetEvent) => void>;
    protected _attributeEventPromise?: Promise<string>;
    protected _attributeEventCallbackMap: Map<string, (e: AttributeEvent) => void>;
    protected _unloading: boolean;
    protected static _subscriptionCounter: number;
    abstract get endpointUrl(): string;
    get status(): EventProviderStatus;
    subscribeStatusChange(callback: (status: EventProviderStatus) => void): void;
    unsubscribeStatusChange(callback: (status: EventProviderStatus) => void): void;
    connect(): Promise<boolean>;
    disconnect(): void;
    subscribe<T extends SharedEvent>(eventSubscription: EventSubscription<T>, callback: (event: T) => void): Promise<string>;
    unsubscribe<T extends SharedEvent>(subscriptionId: string): Promise<void>;
    sendEvent<T extends SharedEvent>(event: T): void;
    sendEventWithReply<T extends SharedEvent, U extends SharedEvent>(event: T): Promise<U>;
    subscribeAssetEvents(ids: string[] | AttributeRef[] | undefined, requestCurrentValues: boolean, callback: (event: AssetEvent) => void): Promise<string>;
    subscribeAttributeEvents(ids: string[] | AttributeRef[] | undefined, requestCurrentValues: boolean, callback: (event: AttributeEvent) => void): Promise<string>;
    protected _processNextSubscription(): void;
    private _onStatusChanged;
    protected _onMessageReceived(subscriptionId: string, event: SharedEvent): void;
    protected _onConnect(): void;
    protected _onDisconnect(): void;
    protected _scheduleReconnect(): void;
    protected abstract _doSend<T extends SharedEvent>(event: T): void;
    protected abstract _doSendWithReply<T extends SharedEvent, U extends SharedEvent>(event: T): Promise<U>;
    protected abstract _doConnect(): Promise<boolean>;
    protected abstract _doDisconnect(): void;
    protected abstract _doSubscribe<T extends SharedEvent>(subscription: EventSubscription<T>): Promise<string>;
    protected abstract _doUnsubscribe(subscriptionId: string): void;
}
export declare class WebSocketEventProvider extends EventProviderImpl {
    protected static _subscriptionCounter: number;
    private readonly _endpointUrl;
    protected _webSocket: WebSocket | undefined;
    protected _connectDeferred: Deferred<boolean> | null;
    protected _subscribeDeferred: Deferred<string> | null;
    protected _repliesDeferred: Map<string, Deferred<SharedEvent>>;
    get endpointUrl(): string;
    constructor(managerUrl: string);
    protected _doConnect(): Promise<boolean>;
    protected _beforeDisconnect(): void;
    protected _doDisconnect(): void;
    protected _doSubscribe<T extends SharedEvent>(subscription: EventSubscription<T>): Promise<string>;
    protected _doUnsubscribe(subscriptionId: string): void;
    protected _doSend<T extends SharedEvent>(event: T): void;
    protected _doSendWithReply<T extends SharedEvent, U extends SharedEvent>(event: T): Promise<U>;
}
export {};
//# sourceMappingURL=event.d.ts.map