import CancellationToken from 'cancellationtoken';
import { Channel, ChannelClass } from './Channel';
import { ChannelOptions } from './ChannelOptions';
import { ControlCode } from './ControlCode';
import { Deferred } from './Deferred';
import { FrameHeader } from './FrameHeader';
import { IChannelOfferEventArgs } from './IChannelOfferEventArgs';
import { IDisposableObservable } from './IDisposableObservable';
import { MultiplexingStreamFormatter } from './MultiplexingStreamFormatters';
import './MultiplexingStreamOptions';
import { MultiplexingStreamOptions } from './MultiplexingStreamOptions';
import { QualifiedChannelId } from './QualifiedChannelId';
export declare abstract class MultiplexingStream implements IDisposableObservable {
    protected readonly formatter: MultiplexingStreamFormatter;
    private readonly isOdd;
    /**
     * The maximum length of a frame's payload.
     */
    static readonly framePayloadMaxLength: number;
    private static readonly recommendedDefaultChannelReceivingWindowSize;
    /** The default window size used for new channels that do not specify a value for ChannelOptions.ChannelReceivingWindowSize. */
    readonly defaultChannelReceivingWindowSize: number;
    protected get disposalToken(): CancellationToken;
    /**
     * Gets a promise that is resolved or rejected based on how this stream is disposed or fails.
     */
    get completion(): Promise<void>;
    /**
     * Gets a value indicating whether this instance has been disposed.
     */
    get isDisposed(): boolean;
    /**
     * Initializes a new instance of the `MultiplexingStream` class.
     * @param stream The duplex stream to read and write to.
     * Use `FullDuplexStream.Splice` if you have distinct input/output streams.
     * @param options Options to customize the behavior of the stream.
     * @param cancellationToken A token whose cancellation aborts the handshake with the remote end.
     * @returns The multiplexing stream, once the handshake is complete.
     */
    static CreateAsync(stream: NodeJS.ReadWriteStream, options?: MultiplexingStreamOptions, cancellationToken?: CancellationToken): Promise<MultiplexingStream>;
    /**
     * Initializes a new instance of the `MultiplexingStream` class
     * with protocolMajorVersion set to 3.
     * @param stream The duplex stream to read and write to.
     * Use `FullDuplexStream.Splice` if you have distinct input/output streams.
     * @param options Options to customize the behavior of the stream.
     * @returns The multiplexing stream.
     */
    static Create(stream: NodeJS.ReadWriteStream, options?: MultiplexingStreamOptions): MultiplexingStream;
    /**
     * The options to use for channels we create in response to incoming offers.
     * @description Whatever these settings are, they can be replaced when the channel is accepted.
     */
    protected static readonly defaultChannelOptions: ChannelOptions;
    /**
     * The encoding used for characters in control frames.
     */
    static readonly ControlFrameEncoding = "utf-8";
    protected readonly _completionSource: Deferred<void>;
    /**
     * A dictionary of channels that were seeded, keyed by their ID.
     */
    protected readonly seededOpenChannels: {
        [id: number]: ChannelClass;
    };
    /**
     * A dictionary of channels that were offered locally, keyed by their ID.
     */
    protected readonly locallyOfferedOpenChannels: {
        [id: number]: ChannelClass;
    };
    /**
     * A dictionary of channels that were offered remotely, keyed by their ID.
     */
    protected readonly remotelyOfferedOpenChannels: {
        [id: number]: ChannelClass;
    };
    /**
     * The last number assigned to a channel.
     * Each use of this should increment by two if isOdd is defined.
     * It should never exceed uint32.MaxValue
     */
    protected abstract lastOfferedChannelId: number;
    /**
     * A map of channel names to queues of channels waiting for local acceptance.
     */
    protected readonly channelsOfferedByThemByName: {
        [name: string]: ChannelClass[];
    };
    /**
     * A map of channel names to queues of Deferred<Channel> from waiting accepters.
     */
    protected readonly acceptingChannels: {
        [name: string]: Deferred<ChannelClass>[];
    };
    /** The major version of the protocol being used for this connection. */
    protected readonly protocolMajorVersion: number;
    private readonly eventEmitter;
    private disposalTokenSource;
    protected constructor(formatter: MultiplexingStreamFormatter, isOdd: boolean | undefined, options: MultiplexingStreamOptions);
    /**
     * Creates an anonymous channel that may be accepted by <see cref="AcceptChannel(int, ChannelOptions)"/>.
     * Its existance must be communicated by other means (typically another, existing channel) to encourage acceptance.
     * @param options A set of options that describe local treatment of this channel.
     * @returns The anonymous channel.
     * @description Note that while the channel is created immediately, any local write to that channel will be
     * buffered locally until the remote party accepts the channel.
     */
    createChannel(options?: ChannelOptions): Channel;
    /**
     * Accepts a channel with a specific ID.
     * @param id The id of the channel to accept.
     * @param options A set of options that describe local treatment of this channel.
     * @description This method can be used to accept anonymous channels created with <see cref="CreateChannel"/>.
     * Unlike <see cref="AcceptChannelAsync(string, ChannelOptions, CancellationToken)"/> which will await
     * for a channel offer if a matching one has not been made yet, this method only accepts an offer
     * for a channel that has already been made.
     */
    acceptChannel(id: number, options?: ChannelOptions): Channel;
    /**
     * Rejects an offer for the channel with a specified ID.
     * @param id The ID of the channel whose offer should be rejected.
     */
    rejectChannel(id: number): void;
    /**
     * Offers a new, named channel to the remote party so they may accept it with
     * {@link acceptChannelAsync}.
     * @param name A name for the channel, which must be accepted on the remote end to complete creation.
     * It need not be unique, and may be empty but must not be null.
     * Any characters are allowed, and max length is determined by the maximum frame payload (based on UTF-8 encoding).
     * @param options A set of options that describe local treatment of this channel.
     * @param cancellationToken A cancellation token. Do NOT let this be a long-lived token
     * or a memory leak will result since we add continuations to its promise.
     * @returns A task that completes with the `Channel` if the offer is accepted on the remote end
     * or faults with `MultiplexingProtocolException` if the remote end rejects the channel.
     */
    offerChannelAsync(name: string, options?: ChannelOptions, cancellationToken?: CancellationToken): Promise<Channel>;
    /**
     * Accepts a channel that the remote end has attempted or may attempt to create.
     * @param name The name of the channel to accept.
     * An empty string will match an offer made via {@link offerChannelAsync} with an empty channel name.
     * It will also match an anonymous channel offer made with {@link createChannel}.
     * @param options A set of options that describe local treatment of this channel.
     * @param cancellationToken A token to indicate lost interest in accepting the channel.
     * Do NOT let this be a long-lived token
     * or a memory leak will result since we add continuations to its promise.
     * @returns The `Channel`, after its offer has been received from the remote party and accepted.
     * @description If multiple offers exist with the specified `name`, the first one received will be accepted.
     */
    acceptChannelAsync(name: string, options?: ChannelOptions, cancellationToken?: CancellationToken): Promise<Channel>;
    /**
     * Disposes the stream.
     */
    dispose(): void;
    protected disposeCore(remoteDisconnect: boolean): void;
    on(event: 'channelOffered', listener: (args: IChannelOfferEventArgs) => void): void;
    off(event: 'channelOffered', listener: (args: IChannelOfferEventArgs) => void): void;
    once(event: 'channelOffered', listener: (args: IChannelOfferEventArgs) => void): void;
    protected raiseChannelOffered(id: number, name: string, isAccepted: boolean): void;
    protected abstract sendFrameAsync(header: FrameHeader, payload: Buffer, cancellationToken: CancellationToken): Promise<void>;
    protected abstract sendFrame(code: ControlCode, channelId: QualifiedChannelId): Promise<void>;
    protected acceptChannelOrThrow(channel: ChannelClass, options?: ChannelOptions): void;
    /**
     * Disposes this instance if the specified promise is rejected.
     * @param promise The promise to check for failures.
     */
    protected rejectOnFailure<T>(promise: Promise<T>): Promise<void>;
    protected removeChannelFromOfferedQueue(channel: ChannelClass): void;
    protected getOpenChannel(qualifiedId: QualifiedChannelId): ChannelClass | undefined;
    protected setOpenChannel(channel: ChannelClass): void;
    protected deleteOpenChannel(qualifiedId: QualifiedChannelId): void;
    private getChannelCollection;
    /**
     * Cancels a prior call to acceptChannelAsync
     * @param channel The promise of a channel to be canceled.
     * @param name The name of the channel the caller was accepting.
     * @param reason The reason for cancellation.
     */
    private acceptChannelCanceled;
    /**
     * Responds to cancellation of a prior call to offerChannelAsync.
     * @param channel The channel previously offered.
     */
    private offerChannelCanceled;
    /**
     * Gets a unique number that can be used to represent a channel.
     * @description The channel numbers increase by two in order to maintain odd or even numbers,
     * since each party is allowed to create only one or the other.
     */
    private getUnusedChannelId;
}
export declare class MultiplexingStreamClass extends MultiplexingStream {
    protected lastOfferedChannelId: number;
    private readonly sendingSemaphore;
    constructor(formatter: MultiplexingStreamFormatter, isOdd: boolean | undefined, options: MultiplexingStreamOptions);
    get backpressureSupportEnabled(): boolean;
    sendFrameAsync(header: FrameHeader, payload?: Buffer, cancellationToken?: CancellationToken): Promise<void>;
    /**
     * Transmits a frame over the stream.
     * @param code The op code for the channel.
     * @param channelId The ID of the channel to receive the frame.
     * @description The promise returned from this function is always resolved (not rejected)
     * since it is anticipated that callers may not be awaiting its result.
     */
    sendFrame(code: ControlCode, channelId: QualifiedChannelId): Promise<void>;
    onChannelWritingCompleted(channel: ChannelClass): void;
    onChannelDisposed(channel: ChannelClass, error: Error | null): Promise<void>;
    localContentExamined(channel: ChannelClass, bytesConsumed: number): void;
    private readFromStream;
    private onOffer;
    private onOfferAccepted;
    private onContent;
    private onContentProcessed;
    private onContentWritingCompleted;
    /**
     * Occurs when the remote party has terminated a channel (including canceling an offer).
     * @param channelId The ID of the terminated channel.
     */
    private onChannelTerminated;
}
