/**
 * @author Martin Karkowski
 * @email m.karkowski@zema.de
 * @create date 2020-01-03 11:52:00
 * @modify date 2022-01-05 17:51:09
 * @desc [description]
 */
import { ILogger } from "js-logger";
import { IAvailableServicesMsg, ICallOptions, ICommunicationBridge, IServiceOptions, IMapBasedMergeData, INopeDispatcherOptions, INopeEventEmitter, INopeObservable, INopePromise, INopeRpcManager, IRequestRpcMsg, IRpcResponseMsg, ITaskCancelationMsg, ValidCallOptions, ValidSelectorFunction } from "../../types/nope/index";
import { INopeConnectivityManager } from "../ConnectivityManager/index";
/**
 * A Dispatcher to perform a function on a Remote
 * Dispatcher. Therefore a Task is created and forwarded
 * to the remote.
 *
 * For a detailled description please checkout {@link INopeRpcManager}
 *
 * @export
 * @class nopeDispatcher
 */
export declare class NopeRpcManager<T extends IServiceOptions = IServiceOptions> implements INopeRpcManager {
    options: INopeDispatcherOptions;
    protected _generateObservable: <T>() => INopeObservable<T>;
    protected _defaultSelector: ValidSelectorFunction;
    protected readonly _id: string;
    protected _connectivityManager: INopeConnectivityManager;
    protected _logger: ILogger;
    /**
     * Internal Element to store the registered Functions
     *
     * @protected
     * @memberof nopeDispatcher
     */
    protected _registeredServices: Map<string, {
        options: T;
        func: (...args: any[]) => Promise<any>;
    }>;
    /**
     * A Mapping of the Services a dispatcher is hosting.
     * Key = Dispatcher-ID
     * Value = Available Services
     *
     * @protected
     * @type {Map<
     *     string,
     *     IAvailableServicesMsg
     *   >}
     * @memberof nopeDispatcher
     */
    protected _mappingOfDispatchersAndServices: Map<string, IAvailableServicesMsg>;
    /**
     * Proxy for accessing the Methods. This proxy provides additional
     * options, which can be used to detail the calls.
     *
     * @author M.Karkowski
     * @memberof NopeRpcManager
     */
    methodInterfaceWithOptions: {
        [index: string]: <T>(options: Partial<ICallOptions>, ...args: any[]) => INopePromise<T>;
    };
    /**
     * Proxy for accessing the Methods. This proxy provides additional
     * options, which can be used to detail the calls.
     *
     * @author M.Karkowski
     * @memberof NopeRpcManager
     */
    methodInterface: {
        [index: string]: <T>(...args: any[]) => INopePromise<T>;
    };
    /**
     * Element showing the available services.
     * Its more or less a map, that maps the
     * services with their dispatchers.
     *
     * - `OriginalKey` = Dispatcher ID (`string`)
     * - `OriginalValue` = Original Message (`IAvailableServicesMsg`)
     * - `ExtractedKey` = Function ID (`string`);`
     * - `ExtractedValue` = FunctionOptions (`T`)
     *
     * @author M.Karkowski
     * @type {IMapBasedMergeData<string>}
     * @memberof INopeRpcManager
     */
    readonly services: IMapBasedMergeData<string, // Dispatcher ID
    IAvailableServicesMsg, // Original Message
    string, // Function ID
    T>;
    /**
     * An event Emitter, which will be called when a task is getting
     * canceled.
     *
     * @author M.Karkowski
     * @type {INopeEventEmitter<ITaskCancelationMsg>}
     * @memberof NopeRpcManager
     */
    readonly onCancelTask: INopeEventEmitter<ITaskCancelationMsg>;
    /**
     * Internal Element to store the running tasks.
     *
     * @protected
     * @memberof nopeDispatcher
     */
    protected _runningInternalRequestedTasks: Map<string, {
        resolve: (value: any) => void;
        reject: (error: any) => void;
        clear: () => void;
        serviceName: string;
        timeout?: any;
        target: string;
    }>;
    /**
     * List, with external tasks, that are running.
     * key = task-id
     * value = id of the requester
     */
    protected _runningExternalRequestedTasks: Map<string, string>;
    /**
     * Flag to show an inital warning
     */
    protected __warned: boolean;
    /**
     * The used Communication interface
     *
     */
    protected readonly _communicator: ICommunicationBridge;
    /**
     * Flag to indicate, that the system is ready.
     *
     * @author M.Karkowski
     * @type {INopeObservable<boolean>}
     * @memberof NopeRpcManager
     */
    readonly ready: INopeObservable<boolean>;
    /**
     * Creates an instance of NopeRpcManager.
     * @param {INopeDispatcherOptions} options The Options, used by the rpc-manager.
     * @param {<T>() => INopeObservable<T>} _generateObservable helper to generate an nope observable. might be used to replace the default observable.
     * @param {ValidSelectorFunction} _defaultSelector Default selector see {@link INopeRpcManager.performCall}
     * @param {string} [_id=null] A Provided a for the rpc-manager
     * @param {INopeConnectivityManager} [_connectivityManager=null] A {@link INopeConnectivityManager} used to listen for new and dead dispatchers
     */
    constructor(options: INopeDispatcherOptions, _generateObservable: <T>() => INopeObservable<T>, _defaultSelector: ValidSelectorFunction, _id?: string, _connectivityManager?: INopeConnectivityManager);
    /**
     * Function, which will be called, if an dispatcher is updated.
     * This may leads to service that has been removed or added.
     * This change emitted on see {@link INopeRpcManager.services}
     *
     * @author M.Karkowski
     * @param {IAvailableServicesMsg} msg The Update Message see {@link IAvailableServicesMsg}
     * @memberof NopeRpcManager
     */
    updateDispatcher(msg: IAvailableServicesMsg): void;
    /**
     * Internal Method to handle the rpcs requests.
     *
     * @protected
     * @param {IRequestRpcMsg} data The provided data of the request
     * @param {(...args) => Promise<any>} [_function]
     * @return {Promise<void>}
     * @memberof NopeRpcManager
     */
    protected _handleExternalRequest(data: IRequestRpcMsg & {
        target?: string;
    }, _function?: (...args: any[]) => Promise<any>): Promise<void>;
    /**
     * Internal Function to handle responses. In Generale,
     * the dispatcher checks if there is an open task with
     * the provided id. If so => finish the promise.
     *
     * @protected
     * @param {IRpcResponseMsg} data The Data provided to handle the Response.
     * @return {boolean} Returns a boolean, indicating whether a corresponding task was found or not.
     * @memberof nopeDispatcher
     */
    protected _handleExternalResponse(data: IRpcResponseMsg): boolean;
    /**
     * Function used to update the Available Services.
     *
     * @protected
     * @memberof nopeDispatcher
     */
    protected _sendAvailableServices(): Promise<void>;
    /**
     * Internal Function, used to initialize the Dispatcher.
     * It subscribes to the "Messages" of the communicator.
     *
     * @protected
     * @memberof nopeDispatcher
     */
    protected _init(): Promise<void>;
    /**
     * Helper to remove a dispatcher. This leads to
     * closing all open task related to this dispatcher ->
     * Exceptions should be thrown. Additional, internal
     * task, requested by the dispatcher will be canceled.
     *
     * @author M.Karkowski
     * @param {string} dispatcher
     * @memberof NopeRpcManager
     */
    removeDispatcher(dispatcher: string): void;
    /**
     * Function to cancel an indivual Task. This might be the case, if a
     * connection to a specific dispatcher is lost or might have a user-based reason.
     *
     * @param {string} taskId The Id of the Task. Which should be canceled.
     * @param {Error} reason The Reason, why the Task should be canceled (In general shoudl be something meaning full)
     * @return {*} Flag, that indicates, whether cancelation was sucessfull or not.
     * @memberof nopeDispatcher
     */
    cancelTask(taskId: string, reason: Error, quiet?: boolean): Promise<boolean>;
    protected _cancelHelper(toCancel: Set<string>, reason: Error): Promise<void>;
    /**
     * Helper Function, used to close all tasks with a specific service.
     *
     * @protected
     * @param {string} serviceName The Name of the Service.
     * @param {Error} reason The provided Reason, why cancelation is reuqired.
     * @memberof nopeDispatcher
     */
    cancelRunningTasksOfService(serviceName: string, reason: Error): Promise<void>;
    /**
     * Helper to cancel all Tasks which have been requested by a Dispatcher.
     *
     * @author M.Karkowski
     * @param {string} dispatcher
     * @param {Error} reason
     * @memberof NopeRpcManager
     */
    cancelRequestedTasksOfDispatcher(dispatcher: string, reason: Error): Promise<void>;
    /**
     * Cancels all Tasks of the given Dispatcher.
     * see {@link NopeRpcManager.cancelTask}
     *
     * @author M.Karkowski
     * @param {string} dispatcher
     * @param {Error} reason
     * @memberof NopeRpcManager
     */
    cancelRunningTasksOfDispatcher(dispatcher: string, reason: Error): Promise<void>;
    /**
     * Function to test if a specific Service exists.
     *
     * @param {string} id The Id of the Serivce
     * @return {boolean} The result of the Test. True if either local or remotly a service is known.
     * @memberof nopeDispatcher
     */
    serviceExists(id: string): boolean;
    /**
     * Simple checker, to test, if this rpc-mananger is providing a service with the given id.
     *
     * @param id The id of the service, which is used during registration
     * @return {boolean} The result
     */
    isProviding(id: string): boolean;
    /**
     * Function to adapt a Request name.
     * Only used internally
     *
     * @protected
     * @param {string} id the original ID
     * @return {string}  the adapted ID.
     * @memberof nopeDispatcher
     */
    protected _getServiceName(id: string, type: "request" | "response"): string;
    /**
     * Function to unregister a Function from the Dispatcher
     * @param {(((...args) => void) | string | number)} func The Function to unregister
     * @return {boolean} Flag, whether the element was removed (only if found) or not.
     * @memberof nopeDispatcher
     */
    unregisterService(func: ((...args: any[]) => void) | string): Promise<boolean>;
    adaptServiceId(name: string): string;
    /**
     * Function to register a Function in the Dispatcher
     *
     * @param {(...args) => Promise<any>} func The function which should be called if a request is mapped to the Function.
     * @param {{
     *     // Flag to enable unregistering the function after calling.
     *     deleteAfterCalling?: boolean,
     *     // Instead of generating a uuid an id could be provided
     *     id?: string;
     *   }} [options={}] Options to enhance the registered ID and enabling unregistering the Element after calling it.
     * @return {(...args) => Promise<any>} The registered Function
     * @memberof nopeDispatcher
     */
    registerService(func: (...args: any[]) => Promise<any>, options: {
        addNopeServiceIdPrefix?: boolean;
    } & T): Promise<(...args: any[]) => Promise<any>>;
    /**
     * Function which is used to perform a call on the remote.
     *
     * @author M.Karkowski
     * @template T
     * @param {string} serviceName serviceName The Name / ID of the Function
     * @param {any[]} params
     * @param {(Partial<ICallOptions> & {
     *       selector?: ValidSelectorFunction;
     *       quiet?: boolean;
     *     })} [options={}] Options for the Call. You can assign a different selector.
     * @return {*}  {INopePromise<T>} The result of the call
     * @memberof nopeDispatcher
     */
    protected _performCall<T>(serviceName: string, params: any[], options?: ValidCallOptions): INopePromise<T>;
    /**
     * Function which is used to perform a call on the remote.
     * Please see {@link INopeRpcManager.performCall} for more Info.
     */
    performCall<T>(serviceName: string | string[], params: unknown[], options?: ValidCallOptions | ValidCallOptions[]): INopePromise<T>;
    /**
     * Function to clear all pending tasks
     *
     * @memberof nopeDispatcher
     */
    clearTasks(): void;
    /**
     * Function to unregister all Functions of the Dispatcher.
     *
     * @memberof nopeDispatcher
     */
    unregisterAll(): void;
    /**
     * Function to reset the Dispatcher.
     *
     * @memberof nopeDispatcher
     */
    reset(): void;
    dispose(): Promise<void>;
    /**
     * Describes the Data.
     * @returns
     */
    toDescription(): {
        services: {
            all: T[];
            internal: {
                options: T;
                func: (...args: any[]) => Promise<any>;
            }[];
        };
        task: {
            executing: string[];
            requested: {
                id: string;
                service: string;
                target: string;
                timeout: any;
            }[];
        };
    };
}
