import { cancellation_exports } from "../utils/cancellation.js";
import { Deferred, isOperationCancelled, startCancelableOperation } from "../utils/promise-utils.js";
var DefaultWorkspaceLock = class {
	constructor() {
		this.previousTokenSource = new cancellation_exports.CancellationTokenSource(), this.writeQueue = [], this.readQueue = [], this.done = !0;
	}
	write(e) {
		this.cancelWrite();
		let t = startCancelableOperation();
		return this.previousTokenSource = t, this.enqueue(this.writeQueue, e, t.token);
	}
	read(e) {
		return this.enqueue(this.readQueue, e);
	}
	enqueue(n, r, i = cancellation_exports.CancellationToken.None) {
		let a = new Deferred(), o = {
			action: r,
			deferred: a,
			cancellationToken: i
		};
		return n.push(o), this.performNextOperation(), a.promise;
	}
	async performNextOperation() {
		if (!this.done) return;
		let e = [];
		if (this.writeQueue.length > 0) e.push(this.writeQueue.shift());
		else if (this.readQueue.length > 0) e.push(...this.readQueue.splice(0, this.readQueue.length));
		else return;
		this.done = !1, await Promise.all(e.map(async ({ action: e, deferred: t, cancellationToken: r }) => {
			try {
				let n = await Promise.resolve().then(() => e(r));
				t.resolve(n);
			} catch (e) {
				isOperationCancelled(e) ? t.resolve(void 0) : t.reject(e);
			}
		})), this.done = !0, this.performNextOperation();
	}
	cancelWrite() {
		this.previousTokenSource.cancel();
	}
};
export { DefaultWorkspaceLock };
