import { RetryOptions } from 'promise.retry';
export { RetryError, TimeoutError } from 'promise.retry';
import { EventEmitter } from 'events';
import { OptionsInit, Progress, Got } from 'got';
export { CacheError, CancelError, HTTPError, MaxRedirectsError, ParseError, Progress, ReadError, RequestError, TimeoutError as RequestTimeoutError, UploadError } from 'got';
import { ProxyAgent } from 'proxy-agent';

interface VampireNewOptions {
    /**
     * use chrome's user-agent
     * @defaultValue `true`
     */
    useChromeUa?: boolean;
    /**
     * use http_proxy / https_proxy environment variables, see {@link https://npm.im/proxy-agent}
     * @defaultValue `true`
     */
    useProxyEnv?: boolean;
    /**
     * more got options
     */
    requestOptions?: OptionsInit;
}
interface ValidateExistingFileOptions {
    /** to skip existing valid cache file ? */
    skipExists?: boolean;
    /**
     * the expected file size, if none provied, a HEAD request
     * will be sent to get the `content-length` header as a fallback.
     * if expectSize matchs existing local file's stat size, then consider existing file is valid
     */
    expectSize?: number;
    /** the expected file hash for validating existing local file */
    expectHash?: string;
    /** the hash algorithm that the expectHash use */
    expectHashAlgorithm?: string;
    /**
     * if expectSize not provided, a HEAD request will be sent to get the `content-length` as expectSize
     * @defaultValue `true`
     */
    useHeadRequestToFetchExpectSize?: boolean;
}
interface DownloadInput {
    /** request url */
    url: string;
    /** local file to save */
    file: string;
}

/**
 * onprogress handler type
 */
type OnProgress = (progress: Progress) => void;
declare class Vampire extends EventEmitter {
    constructor(options?: VampireNewOptions);
    request: Got;
    proxyAgent: ProxyAgent | undefined;
    config(options: VampireNewOptions): void;
    /**
     * get content-length
     */
    getSize(url: string): Promise<number | undefined>;
    /**
     * 是否有需要下载一个文件
     */
    needDownload: ({ url, file, skipExists, expectSize, expectHash, expectHashAlgorithm, useHeadRequestToFetchExpectSize, }: DownloadInput & ValidateExistingFileOptions) => Promise<boolean>;
    /**
     * 下载一个文件
     */
    download: ({ url, file, onprogress }: {
        url: string;
        file: string;
        onprogress?: OnProgress;
    }, signal?: AbortSignal) => Promise<void>;
}

type DlOptions = VampireNewOptions & // new Vampire()
DownloadInput & // file & url
ValidateExistingFileOptions & {
    /** retry options, will pass to promise.retry {@link pretry} */
    retry?: RetryOptions;
    /** on download progress */
    onprogress?: OnProgress;
    /**
     * Print detail before error thrown
     * @defaultValue `true`
     */
    inspectError?: boolean;
};
declare function dl(options: DlOptions): Promise<{
    skip: boolean;
}>;
declare function inspectError(e: Error | undefined, { url, file }: Pick<DlOptions, 'url' | 'file'>): void;

type ReadUrlOptions = Omit<DlOptions, 'file'> & {
    file?: string;
    cacheDir?: string;
    /** maxAge for cache, when string like (1d / 10min) provided, will pass to ms(string) => number */
    maxAge?: number | string;
};
type ReadUrlOptionsWithEncoding = ReadUrlOptions & {
    encoding: BufferEncoding;
};
declare function readUrl(opts: ReadUrlOptions): Promise<Buffer>;
declare function readUrl(opts: ReadUrlOptionsWithEncoding): Promise<string>;
declare function getReadUrlCacheFile(options: Pick<ReadUrlOptions, 'cacheDir' | 'url'>): string;

declare const isGot404Error: (e?: Error) => boolean;
/**
 * test given e is a got.{@link HTTPError} with statusCode = 404
 * or e is a pretry.{@link RetryError} with all member of e.errors is a got.{@link HTTPError}
 */
declare const is404Error: (e?: Error) => boolean;

export { type DlOptions, type OnProgress, type ReadUrlOptions, type ReadUrlOptionsWithEncoding, type ValidateExistingFileOptions, Vampire, type VampireNewOptions, dl as default, dl, getReadUrlCacheFile, inspectError, is404Error, isGot404Error, readUrl };
