import { fileURLToPath as __fileURLToPath } from 'url';
import { dirname as __pathDirname } from 'path';
const __filename = __fileURLToPath(import.meta.url);
const __dirname = __pathDirname(__filename);
class AsyncMutex {
  locked = false;
  waiting = [];
  lockHolder = null;
  lockAcquiredAt = 0;
  lockTimeout;
  constructor(lockTimeoutMs = 3e5) {
    this.lockTimeout = lockTimeoutMs;
  }
  /**
   * Acquire the lock. Waits if already locked.
   * Returns a release function that MUST be called when done.
   */
  async acquire(holder) {
    if (this.locked && this.lockAcquiredAt > 0) {
      const elapsed = Date.now() - this.lockAcquiredAt;
      if (elapsed > this.lockTimeout) {
        console.warn(
          `[AsyncMutex] Stale lock detected (held by ${this.lockHolder} for ${elapsed}ms), forcing release`
        );
        this.forceRelease();
      }
    }
    if (!this.locked) {
      this.locked = true;
      this.lockHolder = holder || "unknown";
      this.lockAcquiredAt = Date.now();
      return () => this.release();
    }
    return new Promise((resolve) => {
      this.waiting.push(() => {
        this.locked = true;
        this.lockHolder = holder || "unknown";
        this.lockAcquiredAt = Date.now();
        resolve(() => this.release());
      });
    });
  }
  /**
   * Try to acquire the lock without waiting
   * Returns release function if acquired, null if already locked
   */
  tryAcquire(holder) {
    if (this.locked && this.lockAcquiredAt > 0) {
      const elapsed = Date.now() - this.lockAcquiredAt;
      if (elapsed > this.lockTimeout) {
        console.warn(
          `[AsyncMutex] Stale lock detected (held by ${this.lockHolder} for ${elapsed}ms), forcing release`
        );
        this.forceRelease();
      }
    }
    if (!this.locked) {
      this.locked = true;
      this.lockHolder = holder || "unknown";
      this.lockAcquiredAt = Date.now();
      return () => this.release();
    }
    return null;
  }
  release() {
    const next = this.waiting.shift();
    if (next) {
      next();
    } else {
      this.locked = false;
      this.lockHolder = null;
      this.lockAcquiredAt = 0;
    }
  }
  forceRelease() {
    this.locked = false;
    this.lockHolder = null;
    this.lockAcquiredAt = 0;
  }
  /**
   * Execute a function while holding the lock
   */
  async withLock(fn, holder) {
    const release = await this.acquire(holder);
    try {
      return await fn();
    } finally {
      release();
    }
  }
  /**
   * Check if currently locked
   */
  isLocked() {
    return this.locked;
  }
  /**
   * Get current lock status
   */
  getStatus() {
    return {
      locked: this.locked,
      holder: this.lockHolder,
      acquiredAt: this.lockAcquiredAt,
      waitingCount: this.waiting.length
    };
  }
}
const syncMutex = new AsyncMutex(3e5);
export {
  AsyncMutex,
  syncMutex
};
//# sourceMappingURL=async-mutex.js.map
