/**
 * Simple mutex implementation for async operations
 */
export class Mutex {
  private isLocked: boolean = false;
  private waitQueue: Array<() => void> = [];

  /**
   * Acquire the lock
   */
  async acquire(): Promise<void> {
    return new Promise<void>((resolve) => {
      if (!this.isLocked) {
        this.isLocked = true;
        resolve();
      } else {
        this.waitQueue.push(resolve);
      }
    });
  }

  /**
   * Release the lock
   */
  release(): void {
    this.isLocked = false;
    const nextResolve = this.waitQueue.shift();
    if (nextResolve) {
      this.isLocked = true;
      nextResolve();
    }
  }

  /**
   * Run a function exclusively with the lock
   */
  async runExclusive<T>(fn: () => Promise<T>): Promise<T> {
    await this.acquire();
    try {
      return await fn();
    } finally {
      this.release();
    }
  }
}