import type { BundleAction, FileAsset, LocationUri, MimeTypeAction } from './squared';

import type { IHost, IModule } from './index';
import type { IAbortComponent } from './core';
import type { FetchType } from './filemanager';
import type { HttpHeaders } from './http';

interface ProcessInit {
    threadCount: number;
    startTime: number;
    timeout: number;
}

export interface BinaryAction {
    binOpts?: string[];
    shellExpansion?: boolean;
}

export interface StreamAction {
    minStreamSize?: number | string;
}

export interface FileData<T extends ExternalAsset> extends MimeTypeAction {
    file: T;
}

export interface FileCommand<T extends ExternalAsset> extends FileData<T> {
    command?: string;
    outputType?: string;
}

export interface IFileThread<T extends IHost = IHost, U extends ExternalAsset = ExternalAsset> extends IAbortComponent, Required<FileData<U>> {
    threadCount: number;
    readonly startTime: number;
    openThread(instance: IModule, timeout?: number): boolean;
    closeThread(instance: IModule, callback?: FunctionType<void>): boolean;
    getObject<V extends FileCommand<U>>(data?: PlainObject): V;
    get host(): T;
    get queuedTasks(): FunctionType<void>[];
    get localUri(): string | undefined;
    set mimeType(value);
    get mimeType(): string;
}

export interface FileThreadConstructor<T extends IHost = IHost, U extends ExternalAsset = ExternalAsset> {
    readonly prototype: IFileThread<T, U>;
    new(host: T, file: U, threadCount: number): IFileThread<T, U>;
}

export interface OutputFinalize<T extends ExternalAsset> extends FileCommand<T> {
    output: string;
    baseDirectory?: string;
}

export interface InitialValue extends Partial<LocationUri>, MimeTypeAction {
    localUri?: string;
    buffer?: Buffer;
    etag?: string;
    cacheable?: boolean;
}

export interface ExternalAsset extends FileAsset, BundleAction, BinaryAction, StreamAction {
    id?: number;
    url?: URL;
    socketPath?: string;
    buffer?: Buffer | null;
    localUri?: string;
    fetchType?: FetchType;
    headers?: HttpHeaders;
    sourceUTF8?: string;
    transforms?: string[];
    descendants?: string[];
    torrentFiles?: string[];
    sourceFiles?: string[];
    initialValue?: InitialValue;
    processModule?: ObjectMap<ProcessInit>;
    etag?: string;
    lastModified?: string;
    contentLength?: number;
    invalid?: boolean;
}

export type HashAlgorithm = "md5" | "sha1" | "sha256" | "sha224" | "sha384" | "sha512" | "ripemd" | "ripemd-160";