/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { ChannelType } from "#net/Channel.js";
import { NetworkError } from "../Network.js";
import { MAX_UDP_MESSAGE_SIZE } from "../udp/UdpChannel.js";
import { MockRouter } from "./MockRouter.js";
class MockUdpChannel {
  #host;
  #router;
  #sendFrom;
  #receiveFrom;
  #listeningPort;
  maxPayloadSize = MAX_UDP_MESSAGE_SIZE;
  constructor(network, { listeningAddress, listeningPort, netInterface, type }, packetManipulator) {
    this.#router = MockRouter(packetManipulator);
    const { ipV4, ipV6 } = network.getIpMac(netInterface ?? "fake0");
    let addresses = type === "udp4" ? ipV4 : ipV6;
    this.#sendFrom = addresses[0];
    if (listeningAddress !== void 0 && listeningAddress !== "*") {
      addresses = addresses.filter((addr) => addr === listeningAddress);
    }
    if (!addresses.length) {
      throw new NetworkError(`No ${type} IP matches ${listeningAddress ?? "*"} on the specified interface`);
    }
    this.#host = network;
    this.#receiveFrom = new Set(addresses);
    this.#listeningPort = listeningPort ?? 1024 + Math.floor(Math.random() * 64511);
    network.router.add(this.#router);
  }
  onData(listener) {
    const router = (packet) => {
      if (packet.kind !== "udp") {
        return;
      }
      if (!this.#receiveFrom.has(packet.destAddress)) {
        return;
      }
      if (packet.destPort !== this.#listeningPort) {
        return;
      }
      listener("fake0", packet.sourceAddress, packet.sourcePort, packet.payload);
    };
    this.#router.add(router);
    return {
      close: async () => {
        this.#router.delete(router);
      }
    };
  }
  async send(host, port, payload) {
    this.#host.simulator.router({
      kind: "udp",
      sourceAddress: this.#sendFrom,
      sourcePort: this.#listeningPort,
      destAddress: host,
      destPort: port,
      payload
    });
  }
  async close() {
    this.#host.router.delete(this.#router);
  }
  async [Symbol.asyncDispose]() {
    return this.close();
  }
  get port() {
    return this.#listeningPort;
  }
  supports(type, _address) {
    return type === ChannelType.UDP;
  }
  addMembership(address) {
    this.#receiveFrom.add(address);
  }
  dropMembership(address) {
    this.#receiveFrom.delete(address);
  }
}
export {
  MockUdpChannel
};
//# sourceMappingURL=MockUdpChannel.js.map
