import { InMemoryStore } from '../backends/memory.js';
import { StoreFS } from '../backends/store/fs.js';
import type { CreationOptions } from './filesystem.js';
import { Inode, type InodeLike } from './inode.js';
/**
 * A device
 * @todo Maybe add some other device information, like a UUID?
 * @category Internals
 * @privateRemarks
 * UUIDs were considered, however they don't make sense without an easy mechanism for persistence
 */
export interface Device<TData = any> {
    /**
     * The device's driver
     */
    driver: DeviceDriver<TData>;
    /**
     * Device metadata
     */
    inode: Inode;
    /**
     * Data associated with a device.
     * This is meant to be used by device drivers.
     */
    data: TData;
    /**
     * Major device number
     */
    major: number;
    /**
     * Minor device number
     */
    minor: number;
}
/**
 * @category Internals
 */
export interface DeviceInit<TData = any> {
    data?: TData;
    minor?: number;
    major?: number;
    name?: string;
    metadata?: Partial<InodeLike>;
}
/**
 * A device driver
 * @category Internals
 */
export interface DeviceDriver<TData = any> {
    /**
     * The name of the device driver
     */
    name: string;
    /**
     * If true, only a single device can exist per device FS.
     * Note that if this is unset or false, auto-named devices will have a number suffix
     */
    singleton?: boolean;
    /**
     * Initializes a new device.
     * @returns `Device.data`
     */
    init?(ino: number, options: object): DeviceInit<TData>;
    /**
     * Synchronously read from a device.
     * @privateRemarks
     * For many devices there is no concept of an offset or end.
     * For example, /dev/random will be "the same" regardless of where you read from- random data.
     * @group File operations
     */
    read(device: Device<TData>, buffer: Uint8Array, offset: number, end: number): void;
    /**
     * Synchronously write to a device
     * @group File operations
     */
    write(device: Device<TData>, buffer: Uint8Array, offset: number): void;
    /**
     * Sync the device
     * @group File operations
     */
    sync?(device: Device<TData>): void;
    /**
     * Close the device
     * @group File operations
     */
    close?(file: Device<TData>): void;
}
/**
 * A temporary file system that manages and interfaces with devices
 * @category Internals
 */
export declare class DeviceFS extends StoreFS<InMemoryStore> {
    protected readonly devices: Map<string, Device<any>>;
    protected devicesWithDriver(driver: DeviceDriver<unknown> | string, forceIdentity?: boolean): Device[];
    /**
     * @internal
     */
    _createDevice<TData = any>(driver: DeviceDriver<TData>, options?: object): Device<TData | Record<string, never>>;
    /**
     * Adds default devices
     */
    addDefaults(): void;
    constructor();
    rename(oldPath: string, newPath: string): Promise<void>;
    renameSync(oldPath: string, newPath: string): void;
    stat(path: string): Promise<InodeLike>;
    statSync(path: string): InodeLike;
    touch(path: string, metadata: InodeLike): Promise<void>;
    touchSync(path: string, metadata: InodeLike): void;
    createFile(path: string, options: CreationOptions): Promise<InodeLike>;
    createFileSync(path: string, options: CreationOptions): InodeLike;
    unlink(path: string): Promise<void>;
    unlinkSync(path: string): void;
    rmdir(path: string): Promise<void>;
    rmdirSync(path: string): void;
    mkdir(path: string, options: CreationOptions): Promise<InodeLike>;
    mkdirSync(path: string, options: CreationOptions): InodeLike;
    readdir(path: string): Promise<string[]>;
    readdirSync(path: string): string[];
    link(target: string, link: string): Promise<void>;
    linkSync(target: string, link: string): void;
    sync(): Promise<void>;
    syncSync(): void;
    read(path: string, buffer: Uint8Array, offset: number, end: number): Promise<void>;
    readSync(path: string, buffer: Uint8Array, offset: number, end: number): void;
    write(path: string, data: Uint8Array, offset: number): Promise<void>;
    writeSync(path: string, data: Uint8Array, offset: number): void;
}
/**
 * Simulates the `/dev/null` device.
 * - Reads return 0 bytes (EOF).
 * - Writes discard data, advancing the file position.
 * @category Internals
 * @internal
 */
export declare const nullDevice: DeviceDriver;
/**
 * Simulates the `/dev/zero` device
 * Provides an infinite stream of zeroes when read.
 * Discards any data written to it.
 *
 * - Reads fill the buffer with zeroes.
 * - Writes discard data but update the file position.
 * - Provides basic file metadata, treating it as a character device.
 * @category Internals
 * @internal
 */
export declare const zeroDevice: DeviceDriver;
/**
 * Simulates the `/dev/full` device.
 * - Reads behave like `/dev/zero` (returns zeroes).
 * - Writes always fail with ENOSPC (no space left on device).
 * @category Internals
 * @internal
 */
export declare const fullDevice: DeviceDriver;
/**
 * Simulates the `/dev/random` device.
 * - Reads return random bytes.
 * - Writes discard data, advancing the file position.
 * @category Internals
 * @internal
 */
export declare const randomDevice: DeviceDriver;
/**
 * Shortcuts for importing.
 * @category Internals
 * @internal
 */
export declare const devices: {
    null: DeviceDriver<any>;
    zero: DeviceDriver<any>;
    full: DeviceDriver<any>;
    random: DeviceDriver<any>;
    console: DeviceDriver<{
        output: (text: string, offset: number) => unknown;
    }>;
};
