"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var DataReadQueue_exports = {};
__export(DataReadQueue_exports, {
  DataReadQueue: () => DataReadQueue
});
module.exports = __toCommonJS(DataReadQueue_exports);
var import_Duration = require("#time/Duration.js");
var import_TimeUnit = require("#time/TimeUnit.js");
var import_MatterError = require("../MatterError.js");
var import_Time = require("../time/Time.js");
var import_Abort = require("./Abort.js");
var import_Error = require("./Error.js");
var import_Promises = require("./Promises.js");
var import_Streams = require("./Streams.js");
/**
 * Promise-based blocking queue.
 *
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
class DataReadQueue {
  #queue = new Array();
  #pendingRead;
  #closed = false;
  async read({ timeout = import_TimeUnit.Minutes.one, abort } = {}) {
    const { promise, resolver, rejecter } = (0, import_Promises.createPromise)();
    if (this.#closed) throw new import_Streams.EndOfStreamError();
    const data = this.#queue.shift();
    if (data !== void 0) {
      return data;
    }
    if (this.#pendingRead !== void 0) throw new import_MatterError.MatterFlowError("Only one pending read is supported");
    this.#pendingRead = {
      resolver,
      rejecter,
      timeoutTimer: import_Time.Time.getTimer(
        "Queue timeout",
        timeout,
        () => rejecter(
          new import_Streams.NoResponseTimeoutError(
            `Expected response data missing within timeout of ${import_Duration.Duration.format(timeout)}`
          )
        )
      ).start()
    };
    let localAbort;
    try {
      if (abort) {
        localAbort = new import_Abort.Abort({
          abort,
          handler: (reason) => {
            this.#clearPendingRead();
            rejecter(reason);
          }
        });
      }
      return await promise;
    } catch (e) {
      if (e instanceof import_MatterError.AbortedError) {
        throw e;
      }
      const error = (0, import_Error.asError)(e);
      error.stack = new Error().stack;
      throw error;
    } finally {
      localAbort?.close();
    }
  }
  write(data) {
    if (this.#closed) throw new import_Streams.EndOfStreamError();
    const pendingRead = this.#pendingRead;
    this.#clearPendingRead();
    if (pendingRead) {
      pendingRead.resolver(data);
      return;
    }
    this.#queue.push(data);
  }
  get size() {
    return this.#queue.length;
  }
  close() {
    if (this.#closed) return;
    this.#closed = true;
    if (this.#pendingRead === void 0) return;
    this.#pendingRead.timeoutTimer?.stop();
    this.#pendingRead.rejecter(new import_Streams.EndOfStreamError());
  }
  #clearPendingRead() {
    if (this.#pendingRead === void 0) {
      return;
    }
    this.#pendingRead.timeoutTimer?.stop();
    this.#pendingRead = void 0;
  }
}
//# sourceMappingURL=DataReadQueue.js.map
