/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { ServerAddress } from "./ServerAddress.js";
function ServerAddressSet(initial, comparator = ServerAddressSet.compareDesirability) {
  let version = 0;
  let addresses;
  const set = {
    add(address) {
      version++;
      const key = ServerAddress.urlFor(address);
      const existing = addresses?.get(key);
      if (existing) {
        return existing;
      }
      if (!addresses) {
        addresses = /* @__PURE__ */ new Map();
      }
      addresses.set(key, address);
      return address;
    },
    delete(address) {
      version++;
      return addresses?.delete(ServerAddress.urlFor(address)) ?? false;
    },
    has(address) {
      return addresses?.has(ServerAddress.urlFor(address)) ?? false;
    },
    replace(newAddresses) {
      version++;
      const oldAddresses = addresses;
      addresses = /* @__PURE__ */ new Map();
      for (const address of newAddresses) {
        const key = ServerAddress.urlFor(address);
        addresses.set(key, oldAddresses?.get(key) ?? address);
      }
    },
    get size() {
      return addresses?.size ?? 0;
    },
    *[Symbol.iterator]() {
      const tried = /* @__PURE__ */ new Set();
      all: while (true) {
        const currentVersion = version;
        const ordered = addresses ? [...addresses.entries()].map(([, address]) => address).sort(comparator) : [];
        for (const address of ordered) {
          const key = ServerAddress.urlFor(address);
          if (tried.has(key)) {
            continue;
          }
          yield address;
          if (currentVersion !== version) {
            continue all;
          }
        }
        break;
      }
    }
  };
  if (initial) {
    set.replace(initial);
  }
  return set;
}
((ServerAddressSet2) => {
  function copyHealth(targetAddresses, sourceAddresses) {
    const output = [...targetAddresses];
    nextTarget: for (let i = 0; i < output.length; i++) {
      const target = output[i];
      for (const source of sourceAddresses) {
        if (ServerAddress.isEqual(target, source)) {
          if (source.healthyAt !== void 0 || source.unhealthyAt !== void 0) {
            output[i] = { ...target, healthyAt: source.healthyAt, unhealthyAt: source.unhealthyAt };
          }
          continue nextTarget;
        }
      }
    }
    return output;
  }
  ServerAddressSet2.copyHealth = copyHealth;
  function compareDesirability(a, b) {
    const value = ServerAddress.selectionPreferenceOf(a) - ServerAddress.selectionPreferenceOf(b);
    if (value) {
      return value;
    }
    const relativeHealth = compareHealth(a, b);
    if (relativeHealth) {
      return relativeHealth;
    }
    if (a.priority !== void 0 && b.priority !== void 0) {
      return b.priority - a.priority;
    }
    return 0;
  }
  ServerAddressSet2.compareDesirability = compareDesirability;
  function compareHealth(a, b) {
    const ha = ServerAddress.healthOf(a);
    const hb = ServerAddress.healthOf(b);
    if (ha.unhealthyAt) {
      if (hb.unhealthyAt) {
        return ha.unhealthyAt - hb.unhealthyAt;
      }
      return 1;
    }
    if (hb.unhealthyAt) {
      return -1;
    }
    if (ha.healthyAt) {
      if (hb.healthyAt) {
        return hb.healthyAt - ha.healthyAt;
      }
      return -1;
    }
    return 0;
  }
  ServerAddressSet2.compareHealth = compareHealth;
})(ServerAddressSet || (ServerAddressSet = {}));
export {
  ServerAddressSet
};
//# sourceMappingURL=ServerAddressSet.js.map
