import IFile from "../storage/IFile";
import LevelKeyValue from "./LevelKeyValue";
import { IErrorMessage, IErrorable } from "../core/IErrorable";
import LevelDbIndex, { ILevelDbFileIndex, ILevelDbLogIndex } from "./LevelDbIndex";
/**
 * Options for initializing LevelDb.
 */
export interface ILevelDbInitOptions {
    /** Whether to unload file content after parsing (default: true for lazy mode) */
    unloadFilesAfterParse?: boolean;
    /**
     * Use lazy loading mode - only load manifest initially, load files on-demand.
     * This dramatically reduces initial memory usage for large worlds.
     * Default: false (full load for backwards compatibility)
     */
    lazyLoad?: boolean;
    /**
     * Maximum number of keys to keep in memory when using lazy mode.
     * Older keys will be evicted when this limit is reached.
     * Default: 50000
     */
    maxKeysInMemory?: number;
    /**
     * Progress callback for loading operations.
     */
    progressCallback?: (phase: string, current: number, total: number) => void;
}
/**
 * Represents chunk coordinates extracted from LevelDB keys.
 * Used for incremental chunk updates when new LDB files are detected.
 */
export interface IChunkCoordinate {
    x: number;
    z: number;
    dimension: number;
}
export default class LevelDb implements IErrorable {
    ldbFiles: IFile[];
    logFiles: IFile[];
    manifestFiles: IFile[];
    keys: Map<string, LevelKeyValue | false | undefined>;
    isInErrorState?: boolean;
    errorMessages?: IErrorMessage[];
    comparator?: string;
    logNumber?: number;
    previousLogNumber?: number;
    nextFileNumber?: number;
    lastSequence?: number;
    compactPointerLevels?: number[];
    compactPointerStrings?: string[];
    deletedFileLevel?: number[];
    deletedFileNumber?: number[];
    newFileLevel?: number[];
    newFileNumber?: number[];
    newFileSize?: number[];
    newFileSmallest?: string[];
    newFileLargest?: string[];
    context?: string;
    /** Index for lazy loading - tracks file metadata without loading content */
    private _index?;
    /** Whether lazy loading mode is enabled */
    private _isLazyMode;
    /** Maximum keys to keep in memory during lazy mode */
    private _maxKeysInMemory;
    /** LRU tracking for key eviction in lazy mode */
    private _keyAccessOrder;
    /** Set of keys that have been loaded but may be evicted */
    private _loadedKeys;
    /** Whether initial metadata has been loaded */
    private _isInitialized;
    /** Get whether lazy loading mode is enabled */
    get isLazyMode(): boolean;
    /** Get the file index for lazy loading */
    get index(): LevelDbIndex | undefined;
    /** Get the number of keys currently in memory */
    get keysInMemoryCount(): number;
    constructor(ldbFileArr: IFile[], logFileArr: IFile[], manifestFilesArr: IFile[], context?: string);
    private _pushError;
    init(log?: (message: string) => Promise<void>, options?: {
        unloadFilesAfterParse?: boolean;
    }): Promise<void>;
    /**
     * Initialize in lazy loading mode - only loads manifest metadata.
     * Files are loaded on-demand when keys are requested.
     *
     * This dramatically reduces initial memory usage for large worlds.
     * Call loadAllFiles() to fully load everything, or use getKey() for on-demand loading.
     */
    initLazy(options?: ILevelDbInitOptions): Promise<void>;
    /**
     * Load all files in lazy mode. This is useful after initLazy() when you want
     * to fully populate all keys (e.g., for world enumeration).
     *
     * @param options Options for loading
     * @returns The number of keys loaded
     */
    loadAllFiles(options?: {
        progressCallback?: (phase: string, current: number, total: number) => void;
        unloadFilesAfterParse?: boolean;
    }): Promise<number>;
    /**
     * Load a specific file's keys into memory.
     * Used for on-demand loading in lazy mode.
     */
    loadFile(fileIndex: ILevelDbFileIndex | ILevelDbLogIndex): Promise<number>;
    private _logFileParsedSizes;
    /**
     * Parse a new or modified LDB/LOG file and return the chunk coordinates affected.
     * This is used for incremental updates when the file system detects new files.
     *
     * @param file The LDB or LOG file to parse
     * @returns Array of unique chunk coordinates affected by keys in this file
     */
    parseIncrementalFile(file: IFile): Promise<IChunkCoordinate[]>;
    /**
     * Extract chunk coordinates from a key name if it represents chunk data.
     */
    private _extractChunkFromKey;
    /**
     * Evict old keys to stay under the memory limit.
     * Uses LRU (least recently used) eviction.
     */
    private _evictKeysIfNeeded;
    /**
     * Track key access for LRU eviction.
     */
    private _trackKeyAccess;
    /**
     * Get a key's value, loading the containing file if necessary (lazy mode).
     * In non-lazy mode, this is a simple map lookup.
     *
     * @param key The key to retrieve
     * @returns The LevelKeyValue, false (if deleted), or undefined (if not found)
     */
    getKey(key: string): Promise<LevelKeyValue | false | undefined>;
    /**
     * Clear all loaded keys and reset to just the index metadata.
     * Useful for freeing memory after processing a world.
     */
    clearLoadedKeys(): void;
    parseLdbContent(content: Uint8Array, context?: string): number | false;
    parseIndexBytes(data: Uint8Array, offset: number, length: number, indexKeys: {
        [id: string]: LevelKeyValue | undefined;
    }, context?: string): boolean;
    parseLdbBlockBytes(data: Uint8Array, offset: number, length: number, context?: string): number;
    parseLogContent(content: Uint8Array, context?: string): number;
    addValueFromLog(content: Uint8Array, index: number, length: number, context?: string): number;
    parseManifestContent(content: Uint8Array, context?: string): void;
    addValueFromManifest(content: Uint8Array, index: number, length: number, context?: string): void;
}
