import { invariant } from "../../../invariant";
import { findIndex } from "../../../native-with-fallback";

const asyncMarshal = () => {
  const entries = [];
  const execute = (timerId) => {
    const index = findIndex(entries, (item) => item.timerId === timerId);
    invariant(index !== -1, "Could not find timer");
    // delete in place
    const [entry] = entries.splice(index, 1);
    entry.callback();
  };
  const add = (fn) => {
    const timerId = setTimeout(() => execute(timerId));
    const entry = {
      timerId,
      callback: fn
    };
    entries.push(entry);
  };
  const flush = () => {
    // nothing to flush
    if (!entries.length) {
      return;
    }
    const shallow = [...entries];
    // clearing entries in case a callback adds some more callbacks
    entries.length = 0;
    shallow.forEach((entry) => {
      clearTimeout(entry.timerId);
      entry.callback();
    });
  };
  return {
    add,
    flush
  };
};

export default asyncMarshal;
