'use strict';
// Request coalescer — batches rapid-fire requests into single executions.
// Inspired by cmux PortScanner.swift kick-coalesce-burst pattern.

/**
 * Creates a coalescer that batches calls within a time window.
 * @param {Function} batchFn - async (items[]) => void, called with collected items
 * @param {Object} [opts]
 * @param {number} [opts.windowMs=200] - Coalesce window in ms
 * @param {number} [opts.maxBatch=100] - Max items per batch (flushes early if reached)
 * @returns {{ push: Function, flush: Function, pending: Function }}
 */
function createCoalescer(batchFn, { windowMs = 200, maxBatch = 100 } = {}) {
  let pending = [];
  let timer = null;

  function flush() {
    if (timer) { clearTimeout(timer); timer = null; }
    if (pending.length === 0) return;
    const batch = pending;
    pending = [];
    // Fire and forget — caller handles errors in batchFn
    Promise.resolve(batchFn(batch)).catch(e => {
      console.warn('[coalescer] Batch execution failed:', e.message);
    });
  }

  function push(item) {
    pending.push(item);
    if (pending.length >= maxBatch) {
      flush();
      return;
    }
    if (!timer) {
      timer = setTimeout(flush, windowMs);
    }
  }

  return {
    push,
    flush,
    pending: () => pending.length,
  };
}

module.exports = { createCoalescer };
