import { Message } from "protobufjs";
import { Observable } from "rxjs";
import { Roster } from "./proto";
import { WebSocketAdapter } from "./websocket-adapter";
/**
 * A connection allows to send a message to one or more distant peers. It has a default
 * service it is connected to, and can only be used to send messages to that service.
 * To change service, a copy has to be created using the copy method.
 */
export interface IConnection {
    /**
     * Send a message to the distant peer
     * @param message   Protobuf compatible message
     * @param reply     Protobuf type of the reply
     * @returns a promise resolving with the reply on success, rejecting otherwise
     */
    send<T extends Message>(message: Message, reply: typeof Message): Promise<T>;
    /**
     * Get the origin of the distant address
     * @returns the address as a string
     */
    getURL(): string;
    /**
     * Set the timeout value for new connections
     * @param value Timeout in milliseconds
     */
    setTimeout(value: number): void;
    /**
     * Creates a copy of the connection, but usable with the given service.
     * @param service
     */
    copy(service: string): IConnection;
    /**
     * Send a message to the distant peer
     * @param message Protobuf compatible message
     * @param reply Protobuf type of the reply
     */
    sendStream<T extends Message>(message: Message, reply: typeof Message): Observable<[T, WebSocketAdapter]>;
    /**
     * Sets how many nodes will be contacted in parallel
     * @deprecated - don't use IConnection for that, but rather directly a
     * RosterWSConnection.
     * @param p number of nodes to contact in parallel
     */
    setParallel(p: number): void;
}
/**
 * Nodes holds all nodes for all services in two lists - one active for the number of
 * parallel open connections, and one reserve pool for connections that can take over if the
 * active list fails.
 *
 * It does some advanced checking of which nodes to contact using the following steps:
 * - sorting the nodes to contact by response time - fastest get contacted first
 * - failing nodes are replaced by currently unused nodes
 * - if a node is slower than the slowThreshold, the node is replaced with a node from the reserve pool
 */
export declare class Nodes {
    static slowThreshold: number;
    private readonly nodeList;
    constructor(r: Roster, previous?: Nodes);
    /**
     * Creates a new NodeList for one message.
     * @param service which service to use
     * @param parallel how many calls will run in parallel
     */
    newList(service: string, parallel: number): NodeList;
    /**
     * Marks the node of the given address as having an error. The error must be
     * a websocket-error 1001 or higher. An error in the request itself (refused
     * transaction) should be treated as a passing node.
     * @param address
     */
    gotError(address: string): void;
    /**
     * Marks the node with the given address as having successfully treated the
     * message. It will re-order the nodes to reflect order of arrival. If the
     * node is more than 10x slower than the fastest node, it will be replaced
     * with a node from the reserve queue.
     * @param address node with successful return
     * @param rang order of arrival
     * @param ratio delay in answer between first reply and this reply
     */
    done(address: string, rang: number, ratio: number): void;
    /**
     * Sets the timeout on all nodes.
     * @param t
     */
    setTimeout(t: number): void;
    /**
     * Returns the IConnections corresponding to the active list and the reserve nodes.
     * @param active how many active nodes to return
     * @param service the chosen service
     */
    splitList(active: number, service: string): [IConnection[], IConnection[]];
    /**
     * Replaces the given node from the active queue with the first node from
     * the reserve queue.
     * @param index
     */
    private replaceActive;
    /**
     * Swaps two nodes in the active queue.
     */
    private swapNodes;
    /**
     * Gets the index of a given address.
     * @param address
     */
    private index;
}
/**
 * A Node holds one IConnection per service.
 */
export declare class Node {
    readonly address: string;
    private services;
    constructor(address: string);
    /**
     * Returns a IConnection for a given service. If the
     * connection doesn't exist yet, it will be created.
     * @param name
     */
    getService(name: string): IConnection;
    /**
     * Sets the timeout for all connections of this node.
     */
    setTimeout(t: number): void;
}
/**
 * A NodeList is used to interact with the Nodes-class by allowing
 * the requester to indicate the order of arrival of messages and
 * which nodes didn't reply correctly.
 */
export declare class NodeList {
    private nodes;
    readonly active: IConnection[];
    private reserve;
    private readonly start;
    private first;
    private replied;
    constructor(nodes: Nodes, service: string, parallel: number);
    /**
     * Returns the total number of nodes.
     */
    readonly length: number;
    /**
     * Replaces the given node with a fresh one. Only to be called in case of websocket-error
     * 1001 or higher.
     * @param ws
     */
    replace(ws: IConnection): IConnection | undefined;
    /**
     * Indicates that this node has successfully finished its job.
     * @param ws
     */
    done(ws: IConnection): number;
}
