import { RawAxiosRequestHeaders, AxiosProxyConfig } from 'axios';
import { Stats } from 'node:fs';
import { ReadEntry } from 'tar';

interface URLInfo {
    protocol: string;
    host: string;
    hostname: string;
    hash: string;
    href: string;
    path: string;
    repository: string;
    owner: string;
    type: string;
}

interface GitlyOptions {
    /**
     * Use cache only (default: undefined)
     */
    cache?: boolean;
    /**
     * Use both cache and local (default: undefined)
     */
    force?: boolean;
    /**
     * Throw an error when fetching (default: undefined)
     */
    throw?: boolean;
    /**
     * Set cache directory (default: '~/.gitly')
     */
    temp?: string;
    /**
     * Set the host name (default: undefined)
     */
    host?: string;
    url?: {
        /**
         * Extend the url filtering method
         * @param info The URLInfo object
         */
        filter?(info: URLInfo): string;
    };
    extract?: {
        /**
         * Extend the extract filtering method for the 'tar' library
         */
        filter?(path: string, stat: Stats | ReadEntry): boolean;
    };
    /**
     * Set the request headers (default: undefined)
     */
    headers?: RawAxiosRequestHeaders;
    /**
     * Set the backend (default: undefined)
     *
     * @example
     * ```markdown
     * 'axios' - default behavior
     * 'git' - use local git installation to clone the repository (allows for cloning private repositories as long as the local git installation has access)
     * ```
     */
    /**
     * Sets the hostname, port, and protocol of the proxy server (default: undefined)
     * Falls back to the https_proxy or http_proxy environment variables if not specified
     */
    proxy?: AxiosProxyConfig;
    backend?: 'axios' | 'git';
    /**
     * Set git options (default: undefined)
     */
    git?: {
        depth?: number;
    };
}

/**
 * Downloads and extracts the repository
 * @param repository The repository to download
 * @param destination The destination to extract
 * @returns A tuple with the source and destination respectively
 */
declare function gitly(repository: string, destination: string, options: GitlyOptions): Promise<[string, string]>;

/**
 * Download the tar file from the repository
 * and store it in a temporary directory
 * @param repository The repository to download
 *
 * @example
 * ```js
 * // ..
 * const path = await download('iwatakeshi/git-copy')
 * // ...
 * ```
 */
declare function download(repository: string, options?: GitlyOptions): Promise<string>;

/**
 * Extract a zipped file to the specified destination
 * @param source The source zipped file
 * @param destination The path to extract the zipped file
 * @param options
 *
 */
declare const _default: (source: string, destination: string, options?: GitlyOptions) => Promise<string>;

/**
 * Parses a url and returns the metadata
 *
 * @example
 * ```markdown
 * 1. owner/repo
 * 2. owner/repo#tag
 * 3. https://host.com/owner/repo
 * 4. host.com/owner/repo
 * 5. host.com/owner/repo#tag
 * 6. host:owner/repo
 * 7. host:owner/repo#tag
 * ```
 */
declare function parse(url: string, options?: GitlyOptions): URLInfo;

/**
 * Uses local git installation to clone a repository to the destination.
 * @param repository The repository to clone
 * @param options The options to use
 * @returns The path to the cloned repository
 * @throws {GitlyCloneError} When the repository fails to clone
 * @note This method requires a local git installation
 * @note This method caches the repository by default
 * @example
 * ```js
 * // ...
 * const path = await clone('iwatakeshi/git-copy')
 * // ...
 * ```
 */
declare function clone(repository: string, options?: GitlyOptions): Promise<string>;

export { clone, gitly as default, download, _default as extract, parse };
