"use strict";
var import_vitest = require("vitest");
var import_utils = require("../../utils.cjs");
var import_output = require("./_output.cjs");
const nextTick = () => new Promise((resolve) => setImmediate(resolve));
(0, import_vitest.describe)("ParticipantAudioOutput waitForPlayoutTask", () => {
  (0, import_vitest.it)("resets tracked duration after non-interrupted playout", async () => {
    let resolvePlayout;
    const waitForPlayout = new Promise((resolve) => {
      resolvePlayout = resolve;
    });
    const output = Object.create(import_output.ParticipantAudioOutput.prototype);
    const onPlaybackFinished = import_vitest.vi.fn();
    output.pushedDuration = 1;
    output.interruptedFuture = new import_utils.Future();
    output.firstFrameEmitted = true;
    output.onPlaybackFinished = onPlaybackFinished;
    output.audioSource = {
      waitForPlayout: () => waitForPlayout,
      queuedDuration: 0,
      clearQueue: import_vitest.vi.fn()
    };
    const task = output.waitForPlayoutTask(new AbortController());
    resolvePlayout();
    await task;
    (0, import_vitest.expect)(output.pushedDuration).toBe(0);
    (0, import_vitest.expect)(onPlaybackFinished).toHaveBeenCalledWith({
      playbackPosition: 1,
      interrupted: false
    });
  });
  (0, import_vitest.it)("resets duration to queue state when interrupted flush clears overlap", async () => {
    let resolvePlayout;
    const waitForPlayout = new Promise((resolve) => {
      resolvePlayout = resolve;
    });
    const output = Object.create(import_output.ParticipantAudioOutput.prototype);
    const onPlaybackFinished = import_vitest.vi.fn();
    output.pushedDuration = 1;
    output.interruptedFuture = new import_utils.Future();
    output.firstFrameEmitted = true;
    output.onPlaybackFinished = onPlaybackFinished;
    output.audioSource = {
      waitForPlayout: () => waitForPlayout,
      queuedDuration: 500,
      clearQueue: import_vitest.vi.fn(() => {
        output.audioSource.queuedDuration = 0;
      })
    };
    const task = output.waitForPlayoutTask(new AbortController());
    output.pushedDuration += 0.5;
    output.interruptedFuture.resolve();
    resolvePlayout();
    await task;
    (0, import_vitest.expect)(output.pushedDuration).toBe(0);
    (0, import_vitest.expect)(onPlaybackFinished).toHaveBeenCalledWith({
      playbackPosition: 0.5,
      interrupted: true
    });
  });
  (0, import_vitest.it)("does not finish one segment twice when flush is called again before playout drains", async () => {
    let resolvePlayout;
    const waitForPlayout = new Promise((resolve) => {
      resolvePlayout = resolve;
    });
    const output = Object.create(import_output.ParticipantAudioOutput.prototype);
    const onPlaybackFinished = import_vitest.vi.fn();
    output.pushedDuration = 1;
    output.interruptedFuture = new import_utils.Future();
    output.firstFrameEmitted = true;
    output.onPlaybackFinished = onPlaybackFinished;
    output.logger = {
      error: import_vitest.vi.fn()
    };
    output.audioSource = {
      waitForPlayout: () => waitForPlayout,
      queuedDuration: 0,
      clearQueue: import_vitest.vi.fn()
    };
    output.flush();
    await nextTick();
    output.flush();
    await nextTick();
    resolvePlayout();
    await nextTick();
    (0, import_vitest.expect)(onPlaybackFinished).toHaveBeenCalledTimes(1);
    (0, import_vitest.expect)(onPlaybackFinished).toHaveBeenCalledWith({
      playbackPosition: 1,
      interrupted: false
    });
    (0, import_vitest.expect)(output.logger.error).not.toHaveBeenCalled();
  });
});
(0, import_vitest.describe)("ParticipantAudioOutput captureFrame segment accounting", () => {
  const makeOutput = (opts) => {
    const output = Object.create(import_output.ParticipantAudioOutput.prototype);
    output.startedFuture = new import_utils.Future();
    output.startedFuture.resolve();
    output.playbackEnabledFuture = new import_utils.Future();
    if (!opts.paused) output.playbackEnabledFuture.resolve();
    output.interruptedFuture = new import_utils.Future();
    output.firstFrameEmitted = false;
    output.pushedDuration = 0;
    output._capturing = false;
    output.playbackSegmentsCount = 0;
    output.playbackFinishedCount = 0;
    output.playbackFinishedFuture = new import_utils.Future();
    output.onPlaybackStarted = import_vitest.vi.fn();
    output.audioSource = { clearQueue: import_vitest.vi.fn(), captureFrame: import_vitest.vi.fn(async () => {
    }) };
    return output;
  };
  const frame = () => ({ samplesPerChannel: 480, sampleRate: 24e3 });
  (0, import_vitest.it)("does not strand the segment counter when a frame is interrupted while paused", async () => {
    const output = makeOutput({ paused: true });
    const capture = output.captureFrame(frame());
    output.interruptedFuture.resolve();
    await capture;
    (0, import_vitest.expect)(output.playbackSegmentsCount).toBe(0);
    (0, import_vitest.expect)(output.audioSource.captureFrame).not.toHaveBeenCalled();
    const result = await Promise.race([
      output.waitForPlayout().then(() => "resolved"),
      new Promise((resolve) => setTimeout(() => resolve("timeout"), 1e3))
    ]);
    (0, import_vitest.expect)(result).toBe("resolved");
  });
  (0, import_vitest.it)("registers a segment on the normal non-paused path", async () => {
    const output = makeOutput({ paused: false });
    await output.captureFrame(frame());
    (0, import_vitest.expect)(output.playbackSegmentsCount).toBe(1);
    (0, import_vitest.expect)(output.audioSource.captureFrame).toHaveBeenCalledTimes(1);
    (0, import_vitest.expect)(output.pushedDuration).toBeGreaterThan(0);
  });
});
//# sourceMappingURL=_output.test.cjs.map