/// <reference types="node" />
import * as net from "net";
import * as tls from "tls";
import { PassThrough, Readable } from "stream";
import * as StreamSearch from "streamsearch";
import DotUnstuffingStreamSearch from "./DotUnstuffingStreamSearch";
import { EventEmitter } from "events";
declare enum Delimiter {
    CRLF = 0,
    MLDB = 1
}
interface ResponseHandler {
    handleResponse: (code: number, message: string, data?: Buffer) => void;
    decideMldb?: (code: number) => boolean;
    MldbStream?: PassThrough;
}
export interface BasicResponse {
    /** Response code. See [RFC 3977 section 3.2](https://tools.ietf.org/html/rfc3977#section-3.2). */
    code: number;
    /** Response message */
    message: string;
}
export interface DataResponse extends BasicResponse {
    /** Content of multi line data block. */
    data?: Buffer;
}
export interface StatResponse {
    /** Response code. See [RFC 3977 section 3.2](https://tools.ietf.org/html/rfc3977#section-3.2). */
    code: number;
    /** Number of selected article. */
    articleNumber: number;
    /** Message id of selected article.  */
    articleId: string;
}
/** NNTP post headers */
export declare type Headers = Record<string, string>;
export interface NntpConnectionConstructorOptions {
    /** Whether dot unstuffing should be performed. (Default: true) */
    dotUnstuffing?: boolean;
}
export interface SteamResponse {
    response: Promise<BasicResponse>;
    stream: Readable;
}
/**
* Emitted when socket is closed.
* @asMemberOf NntpConnection
* @event
*/
export declare function end(): void;
/**
 * Emitted when an socket or protocoll error occurs.
 * @asMemberOf NntpConnection
 * @event
 */
export declare function error(error: Error): void;
/**
 * Emitted when socket timeouts.
 * @asMemberOf NntpConnection
 * @event
 */
export declare function timeout(): void;
/**
 * @noInheritDoc
 */
export declare class NntpConnection extends EventEmitter {
    /** @private */
    _connected: boolean;
    /** @private */
    _connectedResponse: BasicResponse;
    /** @private */
    _socket: net.Socket;
    /** @private */
    _responseQueue: ResponseHandler[];
    /** @private */
    _buffer: Buffer[];
    /** @private */
    _delimiterSearchType: Delimiter;
    /** @private */
    _streamsearchCRLF: StreamSearch;
    /** @private */
    _streamsearchMLDB: DotUnstuffingStreamSearch;
    /**
     *
     * @param options.dotUnstuffing Whether dot unstuffing should be performed.
     */
    constructor(options?: NntpConnectionConstructorOptions);
    /**
     * Connect to nntp server
     * @param options See [TCP options](https://nodejs.org/api/net.html#net_socket_connect_options_connectlistener) or [TLS options](https://nodejs.org/api/tls.html#tls_tls_connect_options_callback).
     * @param secure Whether to use a secure connection
     */
    connect(options: tls.ConnectionOptions | net.NetConnectOpts, secure?: boolean): Promise<BasicResponse>;
    /**
     * Connect to nntp server
     * @param host
     * @param port
     * @param secure Wheter to use a secure connection
     */
    connect(host: string, port: number, secure?: boolean): Promise<BasicResponse>;
    /**
     * @private
     * @param data
     */
    _onData(data: Buffer): void;
    /**
     * @private
     * @param isMatch
     * @param data
     * @param start
     * @param end
     */
    _onInfoCRLF(isMatch: boolean, data: Buffer, start: number, end: number): void;
    /**
     * @private
     * @param isMatch
     * @param data
     * @param start
     * @param end
     */
    _onInfoMLDB(isMatch: boolean, data: Buffer, start: number, end: number): void;
    /**
     * @private
     * @param response
     */
    _getCode(response: string): BasicResponse;
    /**
     * @private
     * @param headString
     */
    _parseHeader(headString: string): Headers;
    /**
     * @private
     * @param response
     */
    _handleResponse(response: string): boolean;
    /**
     * Sends command to server.
     * @param command command to execute
     * @param decideMldb optional function that decides from response code whether a
     * multi line data block is to be expected
     */
    runCommand(command: string, decideMldb?: (code: number) => boolean): Promise<DataResponse>;
    /**
     * Sends command to server. Creates a stream for the multi line data block.
     * @param command command to execute
     * @param decideMldb optional function that decides from response code whether a
     * multi line data block is to be expected
     */
    runCommandStream(command: string, decideMldb?: (code: number) => boolean): SteamResponse;
    /**
     * The CAPABILITIES command allows a client to determine the
     * capabilities of the server at any given time.
     *
     * See [RFC 3977 Section 3.3](https://tools.ietf.org/html/rfc3977#section-3.3)
     * @param keyword
     */
    capabilities(keyword?: string): Promise<DataResponse>;
    /**
     * The MODE READER command instructs a mode-switching server to switch
     * modes, as described in [RFC 3977 Section 3.4.2](https://tools.ietf.org/html/rfc3977#section-3.4.2).
     */
    modeReader(): Promise<BasicResponse>;
    /**
     * The client uses the QUIT command to terminate the session.
     */
    quit(): Promise<BasicResponse>;
    /**
     * The GROUP command selects a newsgroup as the currently selected
     * newsgroup and returns summary information about it.
     * @param group
     */
    group(group: string): Promise<{
        code: number;
        number: number;
        low: number;
        high: number;
        group: string;
    }>;
    /**
     * The LISTGROUP command selects a newsgroup in the same manner as the
     * GROUP command but also provides a list of article
     * numbers in the newsgroup.  If no group is specified, the currently
     * selected newsgroup is used.
     *
     * @param group
     * @param range
     */
    listgroup(group?: string, range?: string): Promise<{
        code: number;
        message: string;
        articles: number[];
    }>;
    /**
     * The current article number will be set to the previous article in
     * that newsgroup
     */
    last(): Promise<StatResponse>;
    /**
     * The current article number will be set to the next article in
     * that newsgroup
     */
    next(): Promise<StatResponse>;
    /**
     * The ARTICLE command selects an article according to the arguments and
     * presents the entire article (that is, the headers, and the body) to
     * the client.
     *
     * @param messageid
     */
    article(messageid?: string | number): Promise<{
        code: number;
        headers: Headers;
        body: Buffer;
    }>;
    /**
     * The HEAD command selects an article according to the arguments and
     * presents the headers to the client.
     *
     * @param messageid
     */
    head(messageid?: string | number): Promise<{
        code: number;
        headers: Headers;
    }>;
    /**
     * The BODY command selects an article according to the arguments and
     * presents the body to the client.
     *
     * @param messageid
     */
    body(messageid?: string | number): Promise<{
        code: number;
        body: Buffer;
    }>;
    /**
     * The BODY command selects an article according to the arguments and
     * presents the body to the client. Body is given as stream.
     * @param messageid
     */
    bodyStream(messageid?: string | number): SteamResponse;
    /**
    * The STAT command selects an article according to the arguments.
    * This command allows the client to determine whether an article exists
    * and what its message-id is, without having to process an arbitrary
    * amount of text.
    *
    * @param messageid
    */
    stat(messageid?: string | number): Promise<StatResponse>;
    /**
     * This command exists to help clients find out the current Coordinated
     * Universal Time from the server's perspective.
     */
    date(): Promise<{
        code: number;
        date: Date;
    }>;
    /**
     * This command provides a short summary of the commands that are
     * understood by this implementation of the server.
     */
    help(): Promise<BasicResponse>;
    /**
     * This command returns a list of newsgroups created on the server since
     * the specified date and time.
     * @param date
     */
    newsgroups(date: Date): Promise<DataResponse>;
    newsgroups(date: string, time: string, gmt?: boolean): Promise<DataResponse>;
}
export {};
