/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { Time } from "#time/Time.js";
class MockTcpConnection {
  remoteAddress;
  remotePort;
  localPort;
  #peer;
  #closeListeners = /* @__PURE__ */ new Set();
  #errorListeners = /* @__PURE__ */ new Set();
  #closed = false;
  /** Queue for async iteration — chunks waiting to be consumed. */
  #chunks = new Array();
  /** Resolver for a pending next() call waiting for data. */
  #waiter;
  constructor(localPort, remoteAddress, remotePort) {
    this.localPort = localPort;
    this.remoteAddress = remoteAddress;
    this.remotePort = remotePort;
  }
  /**
   * Create a connected pair of mock TCP connections.
   */
  static createPair(clientAddress, clientPort, serverAddress, serverPort) {
    const client = new MockTcpConnection(clientPort, serverAddress, serverPort);
    const server = new MockTcpConnection(serverPort, clientAddress, clientPort);
    client.#peer = server;
    server.#peer = client;
    return [client, server];
  }
  async send(data) {
    if (this.#closed) {
      throw new Error("Connection is closed");
    }
    const peer = this.#peer;
    if (!peer || peer.#closed) {
      throw new Error("Peer connection is closed");
    }
    await Time.macrotask;
    if (peer.#closed) return;
    if (peer.#waiter) {
      const resolve = peer.#waiter;
      peer.#waiter = void 0;
      resolve({ value: data, done: false });
    } else {
      peer.#chunks.push(data);
    }
  }
  [Symbol.asyncIterator]() {
    return {
      next: () => {
        if (this.#chunks.length > 0) {
          return Promise.resolve({ value: this.#chunks.shift(), done: false });
        }
        if (this.#closed) {
          return Promise.resolve({ value: void 0, done: true });
        }
        return new Promise((resolve) => {
          this.#waiter = resolve;
        });
      }
    };
  }
  onClose(listener) {
    this.#closeListeners.add(listener);
    return {
      close: async () => {
        this.#closeListeners.delete(listener);
      }
    };
  }
  onError(listener) {
    this.#errorListeners.add(listener);
    return {
      close: async () => {
        this.#errorListeners.delete(listener);
      }
    };
  }
  async close() {
    if (this.#closed) {
      return;
    }
    this.#closed = true;
    this.#waiter?.({ value: void 0, done: true });
    this.#waiter = void 0;
    for (const listener of this.#closeListeners) {
      listener();
    }
    const peer = this.#peer;
    if (peer && !peer.#closed) {
      peer.#closed = true;
      peer.#waiter?.({ value: void 0, done: true });
      peer.#waiter = void 0;
      for (const listener of peer.#closeListeners) {
        listener();
      }
    }
  }
}
export {
  MockTcpConnection
};
//# sourceMappingURL=MockTcpConnection.js.map
