/// <reference types="node" />
import BitField from 'bitfield';
import stream from 'readable-stream';
import { ExtendedHandshake } from './Extension';
import { IExtension } from './models/IExtension';
import { PieceRequest, RequestCallback } from './models/PieceRequest';
import { ParseRequest } from './models/ParseRequest';
import { WireEvents } from './models/WireEvents';
import { ExtensionsMap } from './models/ExtensionsMap';
export declare class Wire extends stream.Duplex {
    _debugId: string;
    peerId: string | undefined;
    peerIdBuffer: Buffer | undefined;
    type: 'webrtc' | 'tcpIncoming' | 'tcpOutgoing' | 'webSeed' | null;
    amChoking: boolean;
    amInterested: boolean;
    peerChoking: boolean;
    peerInterested: boolean;
    peerPieces: BitField;
    peerExtensions: ExtensionsMap;
    requests: PieceRequest[];
    peerRequests: PieceRequest[];
    extendedMapping: {
        [key: number]: string;
    };
    peerExtendedMapping: {
        [key: string]: number;
    };
    extendedHandshake: ExtendedHandshake;
    peerExtendedHandshake: ExtendedHandshake;
    _ext: {
        [extensionName: string]: IExtension;
    };
    _nextExt: number;
    uploaded: number;
    downloaded: number;
    uploadSpeed: (speed: number) => void;
    downloadSpeed: (speed: number) => void;
    _keepAliveInterval: number | NodeJS.Timeout | undefined;
    _timeout: number | NodeJS.Timeout | undefined;
    _timeoutMs: number;
    destroyed: boolean;
    _finished: boolean;
    _parseRequests: Array<ParseRequest>;
    _buffer: Buffer;
    _timeoutUnref: unknown;
    _handshakeSent: boolean;
    _extendedHandshakeSent: boolean;
    _handshakeSuccess: boolean;
    _extendedHandshakeSuccess: boolean;
    wireName: string | undefined;
    constructor(name?: string);
    once<U extends keyof WireEvents>(event: U, listener: WireEvents[U]): this;
    on<U extends keyof WireEvents>(event: U, listener: WireEvents[U]): this;
    off<U extends keyof WireEvents>(event: U, listener: WireEvents[U]): this;
    emit<U extends keyof WireEvents>(event: U, ...args: Parameters<WireEvents[U]>): boolean;
    /**
     * Set whether to send a "keep-alive" ping (sent every 55s)
     * @param {boolean} enable
     */
    setKeepAlive(enable: boolean): void;
    /**
     * Set the amount of time to wait before considering a request to be "timed out"
     * @param {number} ms
     * @param {boolean=} unref (should the timer be unref'd? default: false)
     */
    setTimeout(ms: number, unref?: boolean): void;
    destroy(): this;
    end(...args: any[]): void;
    /**
     * Use the specified protocol extension.
     * @param  {function} Extension
     */
    use(newExtension: (wire: Wire) => IExtension): void;
    /**
     * Message "keep-alive": <len=0000>
     */
    keepAlive(): void;
    /**
     * Message: "handshake" <pstrlen><pstr><reserved><info_hash><peer_id>
     * @param  {Buffer|string} infoHash (as Buffer or *hex* string)
     * @param  {Buffer|string} peerId
     * @param  {Object} extensions
     */
    handshake(infoHash: Buffer | string, peerId: Buffer | string, extensions?: any): void;
    private _sendExtendedHandshake;
    /**
     * Message "choke": <len=0001><id=0>
     */
    choke(): void;
    /**
     * Message "unchoke": <len=0001><id=1>
     */
    unchoke(): void;
    /**
     * Message "interested": <len=0001><id=2>
     */
    interested(): void;
    /**
     * Message "uninterested": <len=0001><id=3>
     */
    uninterested(): void;
    /**
     * Message "have": <len=0005><id=4><piece index>
     * @param  {number} index
     */
    have(index: number): void;
    /**
     * Message "bitfield": <len=0001+X><id=5><bitfield>
     * @param  {BitField|Buffer} bitfield
     */
    bitfield(bitfield: BitField | Buffer): void;
    /**
     * Callback will be resolved when onPiece(index, offset, length, buffer) is called or something fails when requesting.
     *
     * NOTE: index,offset,length are used as a key to look up the callback later.
     *
     * So make sure you specify the length correctly or you will never get your callback.
     *
     * If the other party sends the same index and offset but a buffer of a different length, you will not recieve your callback.
     *
     * Message "request": <len=0013><id=6><index><begin><length>
     * @param  {number}   index
     * @param  {number}   offset
     * @param  {number}   length
     * @param  {function} cb
     */
    request(index: number, offset: number, length: number, cb: RequestCallback): void;
    /**
     * Message "piece": <len=0009+X><id=7><index><begin><block>
     * @param  {number} index
     * @param  {number} offset
     * @param  {Buffer} buffer
     */
    piece(index: number, offset: number, buffer: Buffer): void;
    /**
     * Message "cancel": <len=0013><id=8><index><begin><length>
     * @param  {number} index
     * @param  {number} offset
     * @param  {number} length
     */
    cancel(index: number, offset: number, length: number): void;
    /**
     * Message: "port" <len=0003><id=9><listen-port>
     * @param {Number} port
     */
    port(port: number): void;
    /**
     * Message: "extended" <len=0005+X><id=20><ext-number><payload>
     * @param  {number|string} ext
     * @param  {Object} obj
     */
    extended(ext: number | string, obj: object): void;
    /**
     * Duplex stream method. Called whenever the remote peer stream wants data. No-op
     * since we'll just push data whenever we get it.
     */
    _read(): void;
    /**
     * Send a message to the remote peer.
     */
    private _message;
    private _push;
    private _onKeepAlive;
    private _onHandshake;
    private _onChoke;
    private _onUnchoke;
    private _onInterested;
    private _onUninterested;
    private _onHave;
    private _onBitField;
    private _onRequest;
    private _onPiece;
    private _onCancel;
    private _onPort;
    private onExtendedMessage;
    private onExtendedHandshake;
    private _onExtended;
    private _onTimeout;
    /**
     * Duplex stream method. Called whenever the remote peer has data for us. Data that the
     * remote peer sends gets buffered (i.e. not actually processed) until the right number
     * of bytes have arrived, determined by the last call to `this._parse(number, callback)`.
     * Once enough bytes have arrived to process the message, the callback function
     * (i.e. `this._parser`) gets called with the full buffer of data.
     * @param  {Buffer} data
     * @param  {string} encoding
     * @param  {function} cb
     */
    _write(data: Buffer, encoding: string, cb: (e: any) => void): void;
    private parseStream;
    private _callback;
    private _clearTimeout;
    private _updateTimeout;
    /**
     * Takes a number of bytes that the local peer is waiting to receive from the remote peer
     * in order to parse a complete message, and a callback function to be called once enough
     * bytes have arrived.
     * @param  {number} size
     * @param  {function} parser
     */
    private _parse;
    /**
     * Handle the first 4 bytes of a message, to determine the length of bytes that must be
     * waited for in order to have the whole message.
     * @param  {Buffer} buffer
     */
    private _onMessageLength;
    /**
     * Handle a message from the remote peer.
     * @param  {Buffer} buffer
     */
    private _onMessage;
    private _parseHandshake;
    private _onFinish;
    private _debug;
    /**
     * Retrieves the first entity from the requests array that matches the index, offset and length given.
     *
     * Often used in conjunction with _callback to call back to waiting piece requests
     * @param requests
     * @param pieceIdx
     * @param offset
     * @param length
     */
    private _pull;
}
export default Wire;
