import * as axios from 'axios';

type QBittorrentTorrentState = 'error' | 'missingFiles' | 'uploading' | 'pausedUP' | 'queuedUP' | 'stalledUP' | 'checkingUP' | 'forcedUP' | 'allocating' | 'downloading' | 'metaDL' | 'pausedDL' | 'queuedDL' | 'stalledDL' | 'checkingDL' | 'forcedDL' | 'checkingResumeData' | 'moving' | 'unknown';
interface TorrentInfo {
    added_on: number;
    amount_left: number;
    auto_tmm: boolean;
    availability: number;
    category: string;
    completed: number;
    completion_on: number;
    dl_limit: number;
    dlspeed: number;
    downloaded: number;
    downloaded_session: number;
    eta: number;
    f_l_piece_prio: boolean;
    force_start: boolean;
    hash: string;
    last_activity: number;
    magnet_uri: string;
    max_ratio: number;
    max_seeding_time: number;
    name: string;
    num_complete: number;
    num_incomplete: number;
    num_leechs: number;
    num_seeds: number;
    priority: number;
    progress: number;
    ratio: number;
    ratio_limit: number;
    save_path: string;
    seeding_time_limit: number;
    seen_complete: number;
    seq_dl: boolean;
    size: number;
    state: QBittorrentTorrentState;
    super_seeding: boolean;
    tags: string;
    time_active: number;
    total_size: number;
    tracker: string;
    up_limit: number;
    uploaded: number;
    uploaded_session: number;
    upspeed: number;
}
interface QBittorrentTorrentsAddOptions {
    savepath?: string;
    cookie?: string;
    category?: string;
    tags?: string;
    skip_checking?: boolean;
    paused?: boolean;
    root_folder?: boolean;
    contentLayout?: 'Original' | 'Subfolder' | 'NoSubfolder';
    rename?: string;
    upLimit?: number;
    dlLimit?: number;
    autoTMM?: boolean;
    sequentialDownload?: boolean;
    firstLastPiecePrio?: boolean;
}
declare enum QBittorrentTorrentContentPriority {
    DO_NOT_DOWNLOAD = 0,
    NORMAL = 1,
    HIGH = 6,
    MAXIMUM = 7
}
interface QBittorrentTorrentContent {
    name: string;
    size: number;
    progress: number;
    priority: QBittorrentTorrentContentPriority;
    is_seed: boolean;
    piece_range: Array<number>;
    availability: number;
}
type QBittorrentTorrentContents = Array<QBittorrentTorrentContent>;
interface QBittorrentTorrentProperties {
    save_path: string;
    creation_date: number;
    piece_size: number;
    comment: string;
    total_wasted: number;
    total_uploaded: number;
    total_uploaded_session: number;
    total_downloaded: number;
    total_downloaded_session: number;
    up_limit: number;
    dl_limit: number;
    time_elapsed: number;
    seeding_time: number;
    nb_connections: number;
    nb_connections_limit: number;
    share_ratio: number;
    addition_date: number;
    completion_date: number;
    created_by: string;
    dl_speed_avg: number;
    dl_speed: number;
    eta: number;
    last_seen: number;
    peers: number;
    peers_total: number;
    pieces_have: number;
    pieces_num: number;
    reannounce: number;
    seeds: number;
    seeds_total: number;
    total_size: number;
    up_speed_avg: number;
    up_speed: number;
}
declare enum QBittorrentTorrentTrackerStatus {
    DISABLED = 0,
    NOT_CONTACTED = 1,
    CONTACTED = 2,
    UPDATING = 3,
    ERROR = 4
}
interface QBittorrentTorrentTracker {
    url: string;
    status: QBittorrentTorrentTrackerStatus;
    tier: number;
    num_peers: number;
    num_seeds: number;
    num_leeches: number;
    num_downloaded: number;
    msg: string;
}
type QBittorrentTorrentTrackers = Array<QBittorrentTorrentTracker>;

interface QBittorrentAppPreferences {
    dht: boolean;
    pex: boolean;
    save_path: string;
    max_connec: number;
    max_connec_per_torrent: number;
    max_uploads: number;
    max_uploads_per_torrent: number;
    announce_ip: string;
    listen_port: number;
    random_port: boolean;
    dl_limit: number;
    up_limit: number;
}

interface QBittorrentTransferInfo {
    dl_info_speed: number;
    dl_info_data: number;
    up_info_speed: number;
    up_info_data: number;
    dl_rate_limit: number;
    up_rate_limit: number;
    dht_nodes: number;
    connection_status: 'connected' | 'firewalled' | 'disconnected';
}

interface QBittorrentCategory {
    name: string;
    savePath: string;
}
interface QBittorrentTorrentPeer {
    client: string;
    connection: string;
    country: string;
    country_code: string;
    dl_speed: number;
    downloaded: number;
    up_speed: number;
    uploaded: number;
    files: string;
    flags: string;
    flags_desc: string;
    ip: string;
    port: number;
    progress: number;
    relevance: number;
}
interface QBittorrentSyncMainData {
    rid: number;
    full_update?: boolean;
    categories?: {
        [name: string]: QBittorrentCategory;
    };
    categories_removed?: string[];
    server_state?: QBittorrentTransferInfo;
    tags?: string[];
    tags_removed?: string[];
    torrents?: {
        [hash: string]: TorrentInfo;
    };
    torrents_removed?: string[];
    trackers?: {
        [url: string]: string[];
    };
    trackers_removed: string[];
}
type QBittorrentMainData = Required<Pick<QBittorrentSyncMainData, 'categories' | 'server_state' | 'tags' | 'torrents' | 'trackers'>>;
interface QBittorrentSyncTorrentPeers {
    rid: number;
    peers: {
        [ip_and_port: string]: QBittorrentTorrentPeer;
    };
    peers_removed?: string[];
}
type QBittorrentTorrentPeers = Exclude<QBittorrentSyncTorrentPeers['peers'], undefined>;

interface QBittorrentClientOptions {
    baseUrl: string;
}
declare class QBittorrentClient {
    readonly options: QBittorrentClientOptions;
    httpClient: axios.AxiosInstance;
    sessionCookie?: string;
    constructor(options: QBittorrentClientOptions);
    protected get baseUrl(): string;
    authenticate(username?: string, password?: string): Promise<void>;
    login(username?: string, password?: string): Promise<string | undefined>;
    logout(): Promise<void>;
    version(): Promise<string>;
    getAppPreferences(): Promise<QBittorrentAppPreferences>;
    setAppPreferences(preferences: Partial<QBittorrentAppPreferences>): Promise<void>;
    getTorrentInfos(): Promise<Array<TorrentInfo>>;
    getTorrentContents(hash: string): Promise<QBittorrentTorrentContents>;
    getTorrentProperties(hash: string): Promise<QBittorrentTorrentProperties>;
    getTorrentTrackers(hash: string): Promise<QBittorrentTorrentTrackers>;
    getTransferInfo(): Promise<QBittorrentTransferInfo>;
    syncTorrentPeers(hash: string): Promise<QBittorrentTorrentPeers>;
    torrentsPause(hashes: Array<string>): Promise<void>;
    torrentsResume(hashes: Array<string>): Promise<void>;
    torrentsDelete(hashes: Array<string>, deleteFiles: boolean): Promise<void>;
    torrentsRecheck(hashes: Array<string>): Promise<void>;
    torrentsSetLocation(hashes: Array<string>, location: string): Promise<void>;
    torrentsSetTopPrio(hashes: Array<string>): Promise<void>;
    torrentsSetBottomPrio(hashes: Array<string>): Promise<void>;
    torrentsAddFiles(files: Array<Buffer>, options: QBittorrentTorrentsAddOptions): Promise<void>;
    torrentsAddURLs(urls: Array<string>, options: QBittorrentTorrentsAddOptions): Promise<void>;
    torrentsAddTags(hashes: Array<string>, tags: Array<string>): Promise<void>;
    torrentsRemoveTags(hashes: Array<string>, tags?: Array<string>): Promise<void>;
    torrentsAddTrackers(hash: string, urls: Array<string>): Promise<void>;
    torrentsReannounce(hashes: Array<string>): Promise<void>;
    torrentsRemoveTrackers(hash: string, urls: Array<string>): Promise<void>;
    torrentsSetSuperSeeding(hashes: Array<string>, value: boolean): Promise<void>;
    torrentsToggleSequentialDownload(hashes: Array<string>): Promise<void>;
    torrentsFilePrio(hash: string, ids: Array<number>, priority: QBittorrentTorrentContentPriority): Promise<void>;
}

declare enum ErrorType {
    FORBIDDEN = "FORBIDDEN",
    IP_BANNED = "IP_BANNED",
    INVALID_CREDENTIALS = "INVALID_CREDENTIALS",
    OPERATION_FAILED = "OPERATION_FAILED"
}
interface ErrorContext {
    type?: ErrorType;
}
declare class QBittorrentClientError extends Error {
    readonly name = "QBittorrentClientError";
    readonly type?: ErrorType;
    constructor(message?: string, context?: ErrorContext);
}

export { type ErrorContext, ErrorType, type QBittorrentAppPreferences, type QBittorrentCategory, QBittorrentClient, QBittorrentClientError, type QBittorrentClientOptions, type QBittorrentMainData, type QBittorrentSyncMainData, type QBittorrentSyncTorrentPeers, type QBittorrentTorrentContent, QBittorrentTorrentContentPriority, type QBittorrentTorrentContents, type QBittorrentTorrentPeer, type QBittorrentTorrentPeers, type QBittorrentTorrentProperties, type QBittorrentTorrentState, type QBittorrentTorrentTracker, QBittorrentTorrentTrackerStatus, type QBittorrentTorrentTrackers, type QBittorrentTorrentsAddOptions, type QBittorrentTransferInfo, type TorrentInfo, QBittorrentClient as default };
