import { ConfigOptions } from 'cloudinary';

interface StorageProvider {
    /**
     * Uploads a file to the storage provider.
     * @param file - The file to upload, as a Buffer.
     * @param fileName - The name to give the uploaded file.
     * @param context - Additional context or metadata related to the upload.
     * @returns A Promise that resolves to the URL or identifier of the uploaded file.
     */
    upload(file: Buffer, fileName: string, context: object): Promise<any>;
    /**
     * Downloads a file from the storage provider.
     * @param fileName - The name of the file to download.
     * @param context - Additional context or metadata related to the download.
     * @returns A Promise that resolves to the file data, which could be a Buffer or a ReadableStream.
     */
    download(fileName: string, context: object): Promise<Buffer | ReadableStream<any>>;
    /**
     * Deletes a file from the storage provider.
     * @param fileName - The name of the file to delete.
     * @param context - Additional context or metadata related to the delete operation.
     * @returns A Promise that resolves when the delete operation is complete.
     */
    delete(fileName: string, context: object): Promise<any>;
    /**
     * Lists the files available in the storage provider.
     * @returns A Promise that resolves to an array of file names.
     */
    list(context: object): Promise<string[]>;
    /**
     * Gets the URL or identifier of a file in the storage provider.
     * @param fileName - The name of the file.
     * @param context - Additional context or metadata related to the file.
     * @returns The URL or identifier of the file.
     */
    getUrl(fileName: string, context: object): Promise<string>;
}

type ProviderType = 'cloudinary' | 's3';
declare class StorageFactory {
    static createProvider(type: ProviderType, config: any): StorageProvider;
}

declare class S3Provider implements StorageProvider {
    private s3;
    private bucket;
    constructor(config: {
        accessKeyId: string;
        secretAccessKey: string;
        region: string;
        bucket: string;
    });
    /**
     * Uploads a file to the S3 bucket.
     * @param file - The file data as a Buffer.
     * @param fileName - The name of the file to be uploaded.
     * @param context - Additional context or metadata related to the upload.
     * @returns A Promise that resolves to the data returned by the S3 service.
     */
    upload(file: Buffer, fileName: string, context?: object): Promise<any>;
    /**
     * Downloads a file from the S3 bucket.
     * @param fileName - The name of the file to download.
     * @param context - Additional context or metadata related to the download.
     * @returns A Promise that resolves to the file data, which will be a readable stream for S3.
     */
    download(fileName: string, context?: object): Promise<any>;
    /**
     * Deletes a file from the S3 bucket.
     * @param fileName - The name of the file to delete.
     * @param context - Additional context or metadata related to the deletion.
     * @returns A Promise that resolves to the data returned by the S3 service after the delete operation.
     */
    delete(fileName: string, context?: object): Promise<any>;
    /**
     * Lists all files in the S3 bucket.
     * @param context - Additional context or metadata related to the list operation.
     * @returns A Promise that resolves to an array of file names in the bucket.
     */
    list(context?: object): Promise<string[]>;
    /**
     * Generates a pre-signed URL for accessing a file in the S3 bucket.
     * @param fileName - The name of the file for which to generate the URL.
     * @param context - Additional context or metadata related to the URL generation. Can include an expiration time (`expiresIn`).
     * @returns A Promise that resolves to the pre-signed URL.
     */
    getUrl(fileName: string, context?: {
        expiresIn?: number;
    }): Promise<string>;
}

declare class CloudinaryProvider implements StorageProvider {
    constructor(config: ConfigOptions);
    /**
     * Uploads a file to Cloudinary.
     * @param file - The file data as a Buffer.
     * @param fileName - The name to assign to the uploaded file.
     * @param context - Additional context or metadata related to the upload.
     * @returns A Promise that resolves to the public ID of the uploaded file.
     */
    upload(file: Buffer, fileName: string, context?: object): Promise<any>;
    /**
     * Downloads a file from Cloudinary.
     * @param fileName - The name of the file to download.
     * @param context - Additional context or metadata related to the download.
     * @returns A Promise that resolves to the file data as a Buffer.
     */
    download(fileName: string, context?: object): Promise<any>;
    /**
     * Deletes a file from Cloudinary.
     * @param fileName - The name of the file to delete.
     * @param context - Additional context or metadata related to the deletion.
     * @returns A Promise that resolves when the delete operation completes.
     */
    delete(fileName: string, context?: object): Promise<void>;
    /**
     * Lists all files in Cloudinary.
     * @returns A Promise that resolves to an array of public IDs of the listed files.
     */
    list(context?: object): Promise<string[]>;
    /**
     * Generates a URL for accessing a file in Cloudinary.
     * @param fileName - The name of the file for which to generate the URL.
     * @param context - Additional context or parameters related to the URL generation.
     * @returns A Promise that resolves to the URL of the file.
     */
    getUrl(fileName: string, context?: object): Promise<string>;
}

export { CloudinaryProvider, S3Provider, StorageFactory, type StorageProvider };
