/**
 * AsyncQueue — simple async message queue with blocking dequeue.
 *
 * Used by VoiceSessionManager to relay speech-turn messages to the
 * long-lived agent run loop.  The run loop calls dequeue() which
 * suspends until the next message is enqueued (or a sentinel null
 * is sent to signal termination).
 */
export class AsyncQueue<T> {
  private readonly items: T[] = [];
  private readonly waiters: Array<(item: T) => void> = [];

  enqueue(item: T): void {
    const waiter = this.waiters.shift();
    if (waiter) {
      waiter(item);
    } else {
      this.items.push(item);
    }
  }

  dequeue(): Promise<T> {
    return new Promise<T>((resolve) => {
      if (this.items.length > 0) {
        resolve(this.items.shift()!);
      } else {
        this.waiters.push(resolve);
      }
    });
  }

  /** Resolve all pending dequeue waiters with the given sentinel value (e.g. on shutdown). */
  drain(sentinel: T): void {
    for (const waiter of this.waiters) {
      waiter(sentinel);
    }
    this.waiters.length = 0;
  }
}
