import { stream } from "../utils/stream.js";
import { cancellation_exports } from "../utils/cancellation.js";
import { Deferred, interruptAndCheck } from "../utils/promise-utils.js";
import { URI } from "../../../vscode-uri/lib/esm/index.js";
import { UriUtils } from "../utils/uri-utils.js";
var DefaultWorkspaceManager = class {
	constructor(e) {
		this.initialBuildOptions = {}, this._ready = new Deferred(), this.serviceRegistry = e.ServiceRegistry, this.langiumDocuments = e.workspace.LangiumDocuments, this.documentBuilder = e.workspace.DocumentBuilder, this.fileSystemProvider = e.workspace.FileSystemProvider, this.mutex = e.workspace.WorkspaceLock;
	}
	get ready() {
		return this._ready.promise;
	}
	get workspaceFolders() {
		return this.folders;
	}
	initialize(e) {
		this.folders = e.workspaceFolders ?? void 0;
	}
	initialized(e) {
		return this.mutex.write((e) => this.initializeWorkspace(this.folders ?? [], e));
	}
	async initializeWorkspace(e, r = cancellation_exports.CancellationToken.None) {
		let a = await this.performStartup(e);
		await interruptAndCheck(r), await this.documentBuilder.build(a, this.initialBuildOptions, r);
	}
	async performStartup(n) {
		let r = [], i = (e) => {
			r.push(e), this.langiumDocuments.hasDocument(e.uri) || this.langiumDocuments.addDocument(e);
		};
		await this.loadAdditionalDocuments(n, i);
		let a = [];
		await Promise.all(n.map((e) => this.getRootFolder(e)).map(async (e) => this.traverseFolder(e, a)));
		let o = stream(a).distinct((e) => e.toString()).filter((e) => !this.langiumDocuments.hasDocument(e));
		return await this.loadWorkspaceDocuments(o, i), this._ready.resolve(), r;
	}
	async loadWorkspaceDocuments(e, n) {
		await Promise.all(e.map(async (e) => {
			n(await this.langiumDocuments.getOrCreateDocument(e));
		}));
	}
	loadAdditionalDocuments(e, n) {
		return Promise.resolve();
	}
	getRootFolder(e) {
		return URI.parse(e.uri);
	}
	async traverseFolder(e, n) {
		try {
			let r = await this.fileSystemProvider.readDirectory(e);
			await Promise.all(r.map(async (e) => {
				this.shouldIncludeEntry(e) && (e.isDirectory ? await this.traverseFolder(e.uri, n) : e.isFile && n.push(e.uri));
			}));
		} catch (n) {
			console.error("Failure to read directory content of " + e.toString(!0), n);
		}
	}
	async searchFolder(e) {
		let n = [];
		return await this.traverseFolder(e, n), n;
	}
	shouldIncludeEntry(e) {
		let n = UriUtils.basename(e.uri);
		return n.startsWith(".") ? !1 : e.isDirectory ? n !== "node_modules" && n !== "out" : e.isFile ? this.serviceRegistry.hasServices(e.uri) : !1;
	}
};
export { DefaultWorkspaceManager };
