import { MinQueue } from 'heapify';

// PriorityQueueFast — drop-in replacement for the former
// `@tenere/fast-queue` workspace package, backed by the published
// `heapify` MinQueue (npm, zero-dep, integer keys + priorities).
//
// heapify's MinQueue has a fixed capacity and throws when full;
// this shim doubles capacity on overflow, matching the growth
// semantics the arbiter's stale-eviction queues rely on.
// API: push(key, priority) / pop() / peek() / peekPriority() /
//      clear() / size() / isEmpty() — min-heap by priority.
export class PriorityQueueFast {
  constructor(comparator = undefined, options = {}) {
    this._capacity = Math.max(32, options.initialCapacity || 32);
    this._heap = new MinQueue(this._capacity);
  }

  size() {
    return this._heap.size;
  }

  isEmpty() {
    return this._heap.size === 0;
  }

  peek() {
    return this._heap.size === 0 ? undefined : this._heap.peek();
  }

  peekPriority() {
    return this._heap.size === 0 ? undefined : this._heap.peekPriority();
  }

  push(key, priority) {
    try {
      this._heap.push(key, priority);
    } catch {
      // Capacity reached — pop everything, rebuild at 2x, re-insert.
      const keys = [];
      const priorities = [];
      while (this._heap.size > 0) {
        priorities.push(this._heap.peekPriority());
        keys.push(this._heap.pop());
      }
      this._capacity *= 2;
      this._heap = new MinQueue(this._capacity, keys, priorities);
      this._heap.push(key, priority);
    }
  }

  pop() {
    return this._heap.size === 0 ? undefined : this._heap.pop();
  }

  clear() {
    this._heap.clear();
  }
}
