import type { ChecksumBase, EncodingAction } from './squared';

import type { StreamAction } from './asset';

import type { HashOptions } from 'node:crypto';
import type { Readable } from 'node:stream';

export const enum NORMALIZE_FLAGS {
    NONE = 0,
    RESOLVE = 1,
    ENSURE_DIR = 2,
    POSIX = 4
}

export interface RequireAction {
    requireExt?: string | string[] | boolean;
}

export interface DefaultAction {
    default?: boolean;
    url?: string | URL;
}

export interface ThrowsAction {
    throwsPermission?: boolean;
    throwsDoesNotExist?: boolean;
}

export interface ExecAction {
    uid?: number | string;
    gid?: number | string;
}

export interface IncludeAction<T = string[]> {
    include?: T;
    exclude?: T;
}

export interface PermissionOptions {
    ownPermissionOnly?: boolean;
    hostPermissionOnly?: boolean;
}

export interface FileSystemOptions extends PermissionOptions, ThrowsAction {
    absolutePath?: boolean;
    ignorePermission?: boolean;
}

export interface ReadFileOptions extends FileSystemOptions, StreamBase, RequireAction, EncodingAction, DefaultAction {
    cache?: boolean;
}

export interface WriteFileOptions extends FileSystemOptions, EncodingAction {
    overwrite?: boolean;
}

export interface DeleteFileOptions extends FileSystemOptions {
    emptyDir?: boolean;
}

export interface CopyFileOptions extends FileSystemOptions {
    overwrite?: boolean;
    createDir?: boolean;
    outSrc?: string;
    mode?: number;
}

export interface RemoveDirOptions extends FileSystemOptions {
    emptyDir?: boolean;
    recursive?: boolean;
}

export type MoveFileOptions = CopyFileOptions;
export type CreateDirOptions = FileSystemOptions;

export interface ParseFunctionOptions extends RequireAction, DefaultAction {
    absolute?: boolean;
    sync?: boolean;
    external?: boolean;
    context?: unknown;
}

export interface PackageVersionOptions {
    unstable?: boolean;
    startDir?: string;
    baseDir?: string;
}

export interface CheckSemVerOptions {
    min?: number;
    max?: number;
    equals?: string;
    includes?: boolean;
    startDir?: string;
    unstable: boolean;
}

export interface CopyDirOptions {
    move?: boolean;
    recursive?: boolean | number;
    symFile?: boolean;
    symDir?: boolean;
    ignoreFile?: RegExp;
    ignoreDir?: RegExp;
    silent?: boolean;
    overwrite?: boolean;
}

export interface CopyDirResult {
    success: string[];
    failed: string[];
    ignored: string[];
}

export interface GlobDirOptions {
    exclude?: string | string[];
    recursive?: boolean | number;
    matchBase?: boolean;
    dot?: boolean;
    contains?: boolean;
}

export interface StreamBase extends StreamAction {
    signal?: AbortSignal;
}

export interface ReadHashOptions extends ChecksumBase, StreamBase {
    chunkSize?: number;
}

export interface ReadBufferOptions extends StreamBase, EncodingAction {
    cache?: boolean;
}

export interface AsHashOptions extends HashOptions, ChecksumBase {}

export interface TempDirOptions {
    pathname?: string;
    filename?: string;
    moduleDir?: boolean;
    uuidDir?: boolean;
    createDir?: boolean;
    increment?: number;
}

export type ReadTextOptions = ReadBufferOptions;
export type ReadFileCallback<T extends Bufferable = Bufferable> = (err: NodeJS.ErrnoException | null, data?: T) => void;
export type ProtocolType = "http" | "https" | "http/s" | "ftp" | "sftp" | "s/ftp" | "torrent" | "unc" | "file";
export type PermissionType = "fs" | "memory" | "memory.user" | "worker";
export type FileActionType = "read" | "write" | "delete" | "copy" | "move";
export type DirectoryActionType = "create" | "remove";
export type FileTypeFormat = Bufferable | Uint8Array | ArrayBuffer | Readable;