"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 MdnsAdvertiser_exports = {};
__export(MdnsAdvertiser_exports, {
  MdnsAdvertiser: () => MdnsAdvertiser
});
module.exports = __toCommonJS(MdnsAdvertiser_exports);
var import_Advertiser = require("#advertisement/Advertiser.js");
var import_general = require("@matter/general");
var import_model = require("@matter/model");
var import_types = require("@matter/types");
var import_CommissionableMdnsAdvertisement = require("./CommissionableMdnsAdvertisement.js");
var import_CommissionerMdnsAdvertisement = require("./CommissionerMdnsAdvertisement.js");
var import_OperationalMdnsAdvertisement = require("./OperationalMdnsAdvertisement.js");
/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
class MdnsAdvertiser extends import_Advertiser.Advertiser {
  constructor(crypto, server, options) {
    super(options?.lifetime);
    this.crypto = crypto;
    this.server = server;
    this.port = options?.port ?? import_general.STANDARD_MATTER_PORT;
    this.omitPrivateDetails = options?.omitPrivateDetails ?? false;
    let hasDefaultSchedule = false;
    let hasRetransmitSchedule = false;
    if (options?.schedules) {
      for (const schedule of options.schedules) {
        if (schedule.serviceKind === void 0) {
          if (schedule.event === void 0) {
            hasDefaultSchedule = true;
          }
          if (schedule.event === "retransmit") {
            hasRetransmitSchedule = true;
          }
        }
        this.#schedules.push({ config: schedule });
      }
    }
    if (!hasRetransmitSchedule) {
      this.#schedules.push({ config: MdnsAdvertiser.RetransmissionBroadcastSchedule });
    }
    if (!hasDefaultSchedule) {
      this.#schedules.push({ config: MdnsAdvertiser.DefaultBroadcastSchedule });
    }
  }
  port;
  omitPrivateDetails;
  #schedules = new Array();
  /**
   * Create an advertisement for the specific service.
   */
  getAdvertisement(description) {
    switch (description.kind) {
      case "operational":
        return this.advertisementForFabric(description.fabric) ?? new import_OperationalMdnsAdvertisement.OperationalMdnsAdvertisement(this, description);
      case "commissionable":
        return new import_CommissionableMdnsAdvertisement.CommissionableMdnsAdvertisement(this, description);
      case "commissioner":
        return new import_CommissionerMdnsAdvertisement.CommissionerMdnsAdvertisement(this, description);
      default:
        throw new import_general.ImplementationError(
          `Unsupported service description kind "${description.kind}`
        );
    }
  }
  /**
   * Generate a random 8-byte Matter instance identifier.
   */
  createInstanceId() {
    return import_general.Bytes.toHex(this.crypto.randomBytes(8)).toUpperCase();
  }
  /**
   * Retrieve the broadcast schedule for a specific advertisement.
   */
  broadcastScheduleFor(advertisement, event) {
    const entry = this.#scheduleFor(advertisement, event);
    if (entry.schedule === void 0) {
      entry.schedule = new import_general.RetrySchedule(
        this.crypto,
        import_general.RetrySchedule.Configuration(MdnsAdvertiser.DefaultBroadcastSchedule, entry.config)
      );
    }
    return entry.schedule;
  }
  /**
   * Retrieve broadcast configuration for a specific advertisement.
   */
  broadcastConfigFor(advertisement, event) {
    return this.#scheduleFor(advertisement, event).config;
  }
  #scheduleFor(advertisement, event) {
    if (!event) {
      event = "startup";
    }
    for (const entry of this.#schedules) {
      const { serviceKind, event: event2 } = entry.config;
      if (serviceKind !== void 0 && serviceKind !== advertisement.description.kind) {
        continue;
      }
      if (event2 !== void 0 && event2 !== event) {
        continue;
      }
      return entry;
    }
    throw new import_general.InternalError("Default retry schedule not present");
  }
}
((MdnsAdvertiser2) => {
  MdnsAdvertiser2.DefaultBroadcastSchedule = {
    // Mandated by MDNS specification
    initialInterval: import_general.Seconds.one,
    // Maximum commissioning timeout per Matter specification 5.4.2.3.1, although
    timeout: import_types.MAXIMUM_COMMISSIONING_TIMEOUT,
    // Minimum per MDNS specification
    backoffFactor: 2,
    // Technically this may result in us emitting more than 8 packets which is the maximum per the MDNS
    // specification but extra packets will only come every 90 seconds
    maximumInterval: (0, import_general.Seconds)(90),
    // Not in any specification AFAIK but common sense to reduce thundering herd
    jitterFactor: 0.25,
    // Generally operational broadcast is unnecessary once an operational connection is established
    broadcastAfterConnection: import_general.Instant
  };
  MdnsAdvertiser2.RetransmissionBroadcastSchedule = {
    event: "retransmit",
    // Retransmission events occur for every packet retry so limit count to 1
    maximumCount: 1
  };
  MdnsAdvertiser2.OptionsSchema = new import_model.DatatypeModel(
    { name: "MdnsAdvertiserOptions", type: "struct" },
    (0, import_model.FieldElement)({ name: "omitPrivateDetails", type: "bool" }),
    (0, import_model.FieldElement)(
      { name: "schedules", type: "list" },
      (0, import_model.FieldElement)(
        { name: "entry", type: "struct" },
        (0, import_model.FieldElement)({ name: "initialInterval", type: "uint32" }),
        (0, import_model.FieldElement)({ name: "timeout", type: "uint32" }),
        (0, import_model.FieldElement)({ name: "backoffFactor", type: "uint8" }),
        (0, import_model.FieldElement)({ name: "maximumInterval", type: "uint32" }),
        (0, import_model.FieldElement)({ name: "jitterFactor", type: "single" }),
        (0, import_model.FieldElement)({ name: "serviceKind", type: "string" }),
        (0, import_model.FieldElement)({ name: "event", type: "string" })
      )
    )
  );
})(MdnsAdvertiser || (MdnsAdvertiser = {}));
//# sourceMappingURL=MdnsAdvertiser.js.map
