/**
 * @license
 * Copyright 2022-2024 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { ClusterBehavior } from "#behavior/cluster/ClusterBehavior.js";
import { ClusterServerBacking } from "#behavior/internal/ClusterServerBacking.js";
import { ServerBehaviorBacking } from "#behavior/internal/ServerBehaviorBacking.js";
import { ImplementationError, InternalError, NotImplementedError } from "#general";
const SERVER = Symbol("server");
class EndpointServer {
  #endpoint;
  #name = "";
  #clusterServers = /* @__PURE__ */ new Map();
  get endpoint() {
    return this.#endpoint;
  }
  get deviceType() {
    return this.#endpoint.type.deviceType;
  }
  constructor(endpoint) {
    endpoint[SERVER] = this;
    this.#endpoint = endpoint;
    this.#name = endpoint.type.name;
  }
  createBacking(type) {
    let backing;
    if (type.prototype instanceof ClusterBehavior) {
      const cluster = type.cluster;
      if (this.#clusterServers.has(cluster.id)) {
        throw new InternalError(`${this.#endpoint}.${cluster.id} initialized multiple times`);
      }
      backing = new ClusterServerBacking(this, type);
    } else {
      backing = new ServerBehaviorBacking(this.#endpoint, type);
    }
    return backing;
  }
  get number() {
    return this.#endpoint.number;
  }
  get name() {
    return this.#name;
  }
  getNumber() {
    if (this.number === void 0) {
      throw new InternalError("Endpoint ID has not been assigned yet");
    }
    return this.number;
  }
  removeFromStructure() {
  }
  updatePartsList() {
    return [];
  }
  getChildEndpoints() {
    if (this.#endpoint.hasParts) {
      const parts = this.#endpoint.parts;
      return [...parts].map((endpoint) => EndpointServer.forEndpoint(endpoint));
    }
    return [];
  }
  determineUniqueID() {
    return this.#endpoint.id;
  }
  verifyRequiredClusters() {
    this.#endpoint.behaviors.validateRequirements(this.#endpoint.type.requirements.server?.mandatory);
  }
  close() {
  }
  async [Symbol.asyncDispose]() {
    this.#clusterServers.clear();
    delete this.#endpoint[SERVER];
    for (const endpoint of this.#endpoint.parts) {
      const server = endpoint[SERVER];
      if (server) {
        await server[Symbol.asyncDispose]();
      }
    }
  }
  setStructureChangedCallback() {
  }
  addClusterServer(server) {
    this.#clusterServers.set(server.id, server);
  }
  hasClusterServer(cluster) {
    return this.#clusterServers.has(cluster.id);
  }
  getClusterServer(cluster) {
    const server = this.#clusterServers.get(cluster.id);
    if (server !== void 0) {
      return server;
    }
  }
  getClusterServerById(clusterId) {
    return this.#clusterServers.get(clusterId);
  }
  getAllClusterServers() {
    return [...this.#clusterServers.values()];
  }
  getAllClusterClients() {
    return [];
  }
  addClusterClient() {
    throw new NotImplementedError("Cluster clients unavailable on EndpointServer");
  }
  getClusterClient() {
    throw new NotImplementedError("Cluster clients unavailable on EndpointServer");
  }
  addChildEndpoint(endpoint) {
    if (endpoint instanceof EndpointServer) {
      this.#endpoint.parts.add(endpoint.#endpoint);
    } else {
      throw new ImplementationError("Attempt to add unmanaged endpoint as child of Endpoint");
    }
  }
  getChildEndpoint(id) {
    if (!this.#endpoint.hasParts) {
      return;
    }
    for (const endpoint of this.#endpoint.parts) {
      if (endpoint.number === id) {
        return EndpointServer.forEndpoint(endpoint);
      }
    }
  }
  /**
   * Retrieve the server for an endpoint.
   */
  static forEndpoint(endpoint) {
    let server = endpoint[SERVER];
    if (!server) {
      server = endpoint[SERVER] = new EndpointServer(endpoint);
    }
    return server;
  }
}
export {
  EndpointServer
};
//# sourceMappingURL=EndpointServer.js.map
