import { Driver } from "../typings/Driver";
import { Invoke } from "./Invoke";
import { InvokeEvent } from "./InvokeEvent";
/**
 * The basic communicator.
 *
 * The `Communicator` is an abstract class taking full charge of network communication.
 * Protocolized communicators like {@link WebSocketConnector} are realized by extending this
 * `Communicator` class.
 *
 * You want to make your own communicator using special protocol, extends this `Communicator`
 * class. After the extending, implement your special communicator by overriding those methods.
 *
 *   - {@link inspectReady}
 *   - {@link replyData}
 *   - {@link sendData}
 *
 * @template Provider Type of features provided for remote system.
 * @template Remote Type of features supported by remote system, used for {@link getDriver} function.
 * @author Jeongho Nam - https://github.com/samchon
 */
export declare abstract class Communicator<Provider extends object | null | undefined, Remote extends object | null> {
    /**
     * @hidden
     */
    private static SEQUENCE;
    /**
     * @hidden
     */
    protected provider_: Provider;
    /**
     * @hidden
     */
    private driver_;
    /**
     * @hidden
     */
    private promises_;
    /**
     * @hidden
     */
    private event_listeners_;
    /**
     * @hidden
     */
    private join_cv_;
    /**
     * Initializer Constructor.
     *
     * @param provider An object providing features for remote system.
     */
    protected constructor(provider: Provider);
    /**
     * Add invoke event listener.
     *
     * Add an event listener for the invoke event. The event listener would be called
     * when some invoke event has been occured; sending, receiving, completing, or returning.
     *
     * If you change the requesting parameters or returning value in the event listener,
     * it would affect to the RPC (Remote Procedure Call) communication. Therefore, you have
     * to be careful when modifying the remote function calling.
     *
     * Of course, you can utilize the event listener just for monitoring the RPC events.
     *
     * @param type Type of the event
     * @param listener The listener function to enroll
     */
    on<Type extends InvokeEvent.Type>(type: Type, listener: (event: InvokeEvent.EventMapper[Type]) => void): void;
    /**
     * Erase invoke event listener.
     *
     * Erase an event listener from the invoke event. The event listener would not be
     * called anymore when the specific invoke event has been occured.
     *
     * @param type Type of the event
     * @param listener The listener function to erase
     */
    off<Type extends InvokeEvent.Type>(type: Type, listener: (event: InvokeEvent.EventMapper[Type]) => void): void;
    /**
     * Destroy the communicator.
     *
     * A destroy function must be called when the network communication has been closed.
     * It would destroy all function calls in the remote system (by `Driver<Controller>`),
     * which are not returned yet.
     *
     * The *error* instance would be thrown to those function calls. If the disconnection is
     * abnormal, then write the detailed reason why into the *error* instance.
     *
     * @param error An error instance to be thrown to the unreturned functions.
     */
    protected destructor(error?: Error): Promise<void>;
    /**
     * A predicator inspects whether the *network communication* is on ready.
     *
     * @param method The method name for tracing.
     */
    protected abstract inspectReady(method: string): Error | null;
    /**
     * @hidden
     */
    private _Proxy_func;
    /**
     * @hidden
     */
    private _Call_function;
    /**
     * Set `Provider`
     *
     * @param obj An object would be provided for remote system.
     */
    setProvider(obj: Provider): void;
    /**
     * Get current `Provider`.
     *
     * Get an object providing features (functions & objects) for remote system. The remote
     * system would call the features (`Provider`) by using its `Driver<Controller>`.
     *
     * @return Current `Provider` object
     */
    getProvider(): Provider;
    /**
     * Get Driver for RFC (Remote Function Call).
     *
     * The `Controller` is an interface who defines provided functions from the remote
     * system. The `Driver` is an object who makes to call remote functions, defined in
     * the `Controller` and provided by `Provider` in the remote system, possible.
     *
     * In other words, calling a functions in the `Driver<Controller>`, it means to call
     * a matched function in the remote system's `Provider` object.
     *
     *   - `Controller`: Definition only
     *   - `Driver`: Remote Function Call
     *
     * @template Controller An interface for provided features (functions & objects) from the remote system (`Provider`).
     * @template UseParametric Whether to convert type of function parameters to be compatible with their primitive.
     * @return A Driver for the RFC.
     */
    getDriver<Controller extends NonNullable<Remote> = NonNullable<Remote>, UseParametric extends boolean = false>(): Driver<Controller, UseParametric>;
    /**
     * Join connection.
     *
     * Wait until the connection to be closed.
     */
    join(): Promise<void>;
    /**
     * Join connection or timeout.
     *
     * Wait until the connection to be closed until timeout.
     *
     * @param ms The maximum milliseconds for joining.
     * @return Whether awaken by disconnection or timeout.
     */
    join(ms: number): Promise<boolean>;
    /**
     * Join connection or time expiration.
     *
     * Wait until the connection to be closed until time expiration.
     *
     * @param at The maximum time point to join.
     * @return Whether awaken by disconnection or time expiration.
     */
    join(at: Date): Promise<boolean>;
    /**
     * Data Reply Function.
     *
     * A function should be called when data has come from the remote system.
     *
     * When you receive a message from the remote system, then parse the message with your
     * special protocol and covert it to be an *Invoke* object. After the conversion, call
     * this method.
     *
     * @param invoke Structured data converted by your special protocol.
     */
    protected replyData(invoke: Invoke): void;
    /**
     * @hidden
     */
    private _Handle_function;
    /**
     * @hidden
     */
    private _Handle_complete;
    /**
     * A function sending data to the remote system.
     *
     * @param invoke Structured data to send.
     */
    protected abstract sendData(invoke: Invoke): Promise<void>;
    /**
     * @hidden
     */
    private _Send_return;
}
