import type { DidReceivePluginMessage, DidReceivePropertyInspectorMessage } from "../../api";
import { IDisposable } from "../disposable";
import { EventEmitter } from "../event-emitter";
import type { JsonValue } from "../json";
import { type RawMessageRequest, type RawMessageResponse, type StatusCode } from "./message";
import { MessageResponder } from "./responder";
export declare const PUBLIC_PATH_PREFIX = "public:";
export declare const INTERNAL_PATH_PREFIX = "internal:";
/**
 * Message gateway responsible for sending, routing, and receiving requests and responses.
 */
export declare class MessageGateway<TAction> extends EventEmitter<MessageGatewayEventMap> {
    private readonly proxy;
    private readonly actionProvider;
    /**
     * Requests with pending responses.
     */
    private readonly requests;
    /**
     * Registered routes, and their respective handlers.
     */
    private readonly routes;
    /**
     * Initializes a new instance of the {@link MessageGateway} class.
     * @param proxy Proxy capable of sending messages to the plugin / property inspector.
     * @param actionProvider Action provider responsible for retrieving actions associated with source messages.
     */
    constructor(proxy: OutboundMessageProxy, actionProvider: ActionProvider<TAction>);
    /**
     * Sends the {@link request} to the server; the server should be listening on {@link MessageGateway.route}.
     * @param request The request.
     * @returns The response.
     */
    fetch<T extends JsonValue = JsonValue>(request: MessageRequestOptions): Promise<MessageResponse<T>>;
    /**
     * Sends the request to the server; the server should be listening on {@link MessageGateway.route}.
     * @param path Path of the request.
     * @param body Optional body sent with the request.
     * @returns The response.
     */
    fetch<T extends JsonValue = JsonValue>(path: string, body?: JsonValue): Promise<MessageResponse<T>>;
    /**
     * Attempts to process the specified {@link message}.
     * @param message Message to process.
     * @returns `true` when the {@link message} was processed by this instance; otherwise `false`.
     */
    process(message: DidReceivePluginMessage<JsonValue> | DidReceivePropertyInspectorMessage<JsonValue>): Promise<void>;
    /**
     * Maps the specified {@link path} to the {@link handler}, allowing for requests from the client.
     * @param path Path used to identify the route.
     * @param handler Handler to be invoked when the request is received.
     * @param options Optional routing configuration.
     * @returns Disposable capable of removing the route handler.
     */
    route<TBody extends JsonValue = JsonValue>(path: string, handler: UnscopedMessageHandler<TAction, TBody>, options?: RouteConfiguration<TAction>): IDisposable;
    /**
     * Handles inbound requests.
     * @param action Action associated with the request.
     * @param source The request.
     * @returns `true` when the request was handled; otherwise `false`.
     */
    private handleRequest;
    /**
     * Handles inbound response.
     * @param res The response.
     * @returns `true` when the response was handled; otherwise `false`.
     */
    private handleResponse;
}
/**
 * Represents a message received from the plugin or the property inspector.
 * @template T The type of the payload.
 */
type PluginOrPropertyInspectorMessage<T extends JsonValue> = DidReceivePluginMessage<T> | DidReceivePropertyInspectorMessage<T>;
/**
 * Event map for {@link MessageGateway}.
 */
type MessageGatewayEventMap = {
    /**
     * Occurs when attempting to process a message that cannot be handled by the gateway.
     */
    unhandledMessage: [message: PluginOrPropertyInspectorMessage<JsonValue>];
    /**
     * Occurs when attempting to process a message that represents a request, but cannot be routed.
     */
    unhandledRequest: [message: PluginOrPropertyInspectorMessage<RawMessageRequest>];
};
/**
 * Message request options associated with a request to be sent to the server.
 */
export type MessageRequestOptions = {
    /**
     * Body sent with the request.
     */
    body?: JsonValue;
    /**
     * Path of the request.
     */
    path: string;
    /**
     * Timeout duration in milliseconds; defaults to `5000` (5s).
     */
    timeout?: number;
    /**
     * Indicates whether the request is unidirectional; when `true`, a response will not be awaited.
     */
    unidirectional?: boolean;
};
/**
 * Message response, received from the server.
 */
declare class MessageResponse<TBody extends JsonValue = JsonValue> {
    /**
     * Body of the response.
     */
    readonly body?: TBody;
    /**
     * Status of the response.
     * - `200` the request was successful.
     * - `202` the request was unidirectional, and does not have a response.
     * - `406` the request could not be accepted by the server.
     * - `408` the request timed-out.
     * - `500` the request failed.
     * - `501` the request is not implemented by the server, and could not be fulfilled.
     */
    readonly status: StatusCode;
    /**
     * Initializes a new instance of the {@link MessageResponse} class.
     * @param res The status code, or the response.
     */
    constructor(res: RawMessageResponse);
    /**
     * Indicates whether the request was successful.
     * @returns `true` when the status indicates a success; otherwise `false`.
     */
    get ok(): boolean;
}
export { type MessageResponse };
/**
 * Proxy capable of sending a payload to the plugin / property inspector.
 * @param payload Payload to be sent to the server.
 * @returns `true` when the server was able to accept the response; otherwise `false`.
 */
export type OutboundMessageProxy = (payload: JsonValue) => Promise<boolean> | boolean;
/**
 * Gets the action from the specified source.
 */
export type ActionProvider<T> = (source: DidReceivePluginMessage<JsonValue> | DidReceivePropertyInspectorMessage<JsonValue>) => T;
/**
 * Message request, received from the client.
 * @template TAction The type of the action that sent the request.
 * @template TBody The type of the request body.
 */
export type UnscopedMessageRequest<TAction, TBody extends JsonValue = JsonValue> = Omit<RawMessageRequest, "__type" | "body" | "id"> & {
    /**
     * Action associated with the request.
     */
    readonly action: TAction;
    /**
     * Body of the request.
     */
    readonly body?: TBody;
};
/**
 * Function responsible for handling a request, and providing a response.
 */
export type UnscopedMessageHandler<TAction, TBody extends JsonValue = JsonValue> = (request: UnscopedMessageRequest<TAction, TBody>, response: MessageResponder) => JsonValue | Promise<JsonValue | void> | void;
/**
 * Configuration that defines the route.
 */
export type RouteConfiguration<TAction> = {
    /**
     * Optional filter used to determine if a message can be routed; when `true`, the route handler will be called.
     * @param action Action associated with the message.
     * @returns Should return `true` when the request can be handled; otherwise `false`.
     */
    filter?: (source: TAction) => boolean;
};
