import path from 'path';
import { getNameFromPath } from './utils/get-name-from-path.js';
import { basicSearch } from './utils/basic-search.js';
/**
 * Shared cache for workspace file and folder items, populated by a single tree walk
 * and kept current via file system watcher mutations. Both the file and folder
 * context providers read from this cache instead of maintaining their own.
 */
export class FileSystemCache {
    walkWorkspace;
    files = new Map();
    folders = new Map();
    initPromise;
    constructor(walkWorkspace) {
        this.walkWorkspace = walkWorkspace;
        this.initPromise = this.initialize();
    }
    /** Resolves once the initial tree walk has completed. */
    get isInitialized() {
        return this.initPromise;
    }
    /** Returns all cached file items. */
    async getFiles() {
        await this.initPromise;
        return Array.from(this.files.values());
    }
    /** Returns all cached folder items. */
    async getFolders() {
        await this.initPromise;
        return Array.from(this.folders.values());
    }
    /** Adds a file to the cache. */
    addFile(item) {
        this.files.set(item.path, item);
    }
    /** Removes a file from the cache. */
    removeFile(path) {
        this.files.delete(path);
    }
    /** Adds a folder to the cache. */
    addFolder(item) {
        this.folders.set(item.path, item);
    }
    /** Removes a folder from the cache. */
    removeFolder(path) {
        this.folders.delete(path);
    }
    /** Removes an entry and all descendants from both maps. Handles directory deletes where child events aren't fired. */
    removeTree(dirPath) {
        this.files.delete(dirPath);
        this.folders.delete(dirPath);
        const prefix = dirPath + path.sep;
        for (const key of this.files.keys()) {
            if (key.startsWith(prefix)) {
                this.files.delete(key);
            }
        }
        for (const key of this.folders.keys()) {
            if (key.startsWith(prefix)) {
                this.folders.delete(key);
            }
        }
    }
    /** Returns file items as context items for the file provider. */
    async getFileContextItems() {
        const files = await this.getFiles();
        return this.toFileContextItems(files);
    }
    /** Returns folder items as context items for the folder provider. */
    async getFolderContextItems() {
        const folders = await this.getFolders();
        return this.toFolderContextItems(folders);
    }
    /** Sync substring search across cached file items. Returns matches from whatever is loaded. */
    searchFiles(query) {
        return basicSearch(this.toFileContextItems(Array.from(this.files.values())), query);
    }
    /** Sync substring search across cached folder items. Returns matches from whatever is loaded. */
    searchFolders(query) {
        return basicSearch(this.toFolderContextItems(Array.from(this.folders.values())), query);
    }
    toFileContextItems(items) {
        return items.map(({ path, workspacePath }) => ({
            name: getNameFromPath(path),
            description: workspacePath && path.startsWith(workspacePath) ? path.slice(workspacePath.length) : path,
            query: path,
        }));
    }
    toFolderContextItems(items) {
        return items.map(({ path, workspacePath }) => ({
            name: getNameFromPath(path),
            description: workspacePath && path.startsWith(workspacePath) ? path.slice(workspacePath.length) : path,
            query: path,
        }));
    }
    async initialize() {
        const { files, folders } = await this.walkWorkspace();
        for (const file of files) {
            this.files.set(file.path, file);
        }
        for (const folder of folders) {
            this.folders.set(folder.path, folder);
        }
    }
}
//# sourceMappingURL=file-system-cache.js.map