/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { Diagnostic, Logger } from "#general";
import { Cluster } from "./Cluster.js";
import { ClusterRegistry } from "./ClusterRegistry.js";
const logger = Logger.get("ClusterHelper");
const clusterAttributeCache = /* @__PURE__ */ new Map();
const clusterEventCache = /* @__PURE__ */ new Map();
const clusterCommandCache = /* @__PURE__ */ new Map();
const UnknownCluster = (clusterId) => Cluster({
  id: clusterId,
  name: `Unknown cluster ${toHex(clusterId)}`,
  revision: 0,
  unknown: true
});
function getClusterNameById(clusterId) {
  return ClusterRegistry.get(clusterId)?.name ?? `Unknown cluster ${Diagnostic.hex(clusterId)}`;
}
function getClusterById(clusterId) {
  let cluster = ClusterRegistry.get(clusterId);
  if (cluster === void 0) {
    logger.info(`Unknown cluster ${toHex(clusterId)} requested: UnknownCluster instance added.`);
    cluster = UnknownCluster(clusterId);
    ClusterRegistry.register(cluster);
  }
  return cluster;
}
function getClusterAttributeById(clusterDef, attributeId) {
  if (!clusterAttributeCache.has(clusterDef.id)) {
    const attributeMap2 = /* @__PURE__ */ new Map();
    const { attributes } = clusterDef;
    for (const attributeName in attributes) {
      const attribute = attributes[attributeName];
      attributeMap2.set(attribute.id, { attribute, name: attributeName });
    }
    clusterAttributeCache.set(clusterDef.id, attributeMap2);
    return attributeMap2.get(attributeId);
  }
  const attributeMap = clusterAttributeCache.get(clusterDef.id);
  if (attributeMap === void 0) {
    return void 0;
  }
  return attributeMap.get(attributeId);
}
function getClusterEventById(clusterDef, eventId) {
  if (!clusterEventCache.has(clusterDef.id)) {
    const eventMap2 = /* @__PURE__ */ new Map();
    const { events } = clusterDef;
    for (const eventName in events) {
      const event = events[eventName];
      eventMap2.set(event.id, { event, name: eventName });
    }
    clusterEventCache.set(clusterDef.id, eventMap2);
    return eventMap2.get(eventId);
  }
  const eventMap = clusterEventCache.get(clusterDef.id);
  if (eventMap === void 0) {
    return void 0;
  }
  return eventMap.get(eventId);
}
function getClusterCommandById(clusterDef, commandId) {
  if (!clusterCommandCache.has(clusterDef.id)) {
    const commandMap2 = /* @__PURE__ */ new Map();
    const { commands } = clusterDef;
    for (const commandName in commands) {
      const command = commands[commandName];
      commandMap2.set(command.requestId, { command, name: commandName });
    }
    clusterCommandCache.set(clusterDef.id, commandMap2);
    return commandMap2.get(commandId);
  }
  const commandMap = clusterCommandCache.get(clusterDef.id);
  if (commandMap === void 0) {
    return void 0;
  }
  return commandMap.get(commandId);
}
function toHex(value) {
  return value === void 0 ? "*" : `0x${value.toString(16)}`;
}
function resolveEndpointClusterName(nodeId, endpointId, clusterId) {
  let elementName = nodeId === void 0 ? "" : `${toHex(nodeId)}/`;
  if (endpointId === void 0) {
    elementName += "*";
  } else {
    elementName += `${toHex(endpointId)}`;
  }
  if (clusterId === void 0) {
    return `${elementName}/*`;
  }
  const cluster = getClusterById(clusterId);
  if (cluster.unknown) {
    return `${elementName}/unknown(${toHex(clusterId)})`;
  }
  return `${elementName}/${cluster.name}(${toHex(clusterId)})`;
}
function resolveAttributeName({
  nodeId,
  endpointId,
  clusterId,
  attributeId
}) {
  const endpointClusterName = resolveEndpointClusterName(nodeId, endpointId, clusterId);
  if (endpointId === void 0 || clusterId === void 0 || attributeId === void 0) {
    return `${endpointClusterName}/${toHex(attributeId)}`;
  }
  const cluster = getClusterById(clusterId);
  const attribute = getClusterAttributeById(cluster, attributeId);
  if (attribute === void 0) {
    return `${endpointClusterName}/unknown(${toHex(attributeId)})`;
  }
  return `${endpointClusterName}/${attribute.name}(${toHex(attributeId)})`;
}
function resolveEventName({
  nodeId,
  endpointId,
  clusterId,
  eventId,
  isUrgent
}) {
  const isUrgentStr = isUrgent ? "!" : "";
  const endpointClusterName = resolveEndpointClusterName(nodeId, endpointId, clusterId);
  if (endpointId === void 0 || clusterId === void 0 || eventId === void 0) {
    return `${isUrgentStr}${endpointClusterName}/${toHex(eventId)}`;
  }
  const event = getClusterEventById(getClusterById(clusterId), eventId);
  if (event === void 0) {
    return `${isUrgentStr}${endpointClusterName}/unknown(${toHex(eventId)})`;
  }
  return `${isUrgentStr}${endpointClusterName}/${event.name}(${toHex(eventId)})`;
}
function resolveCommandName({ endpointId, clusterId, commandId }) {
  const endpointClusterName = resolveEndpointClusterName(void 0, endpointId, clusterId);
  if (endpointId === void 0 || clusterId === void 0 || commandId === void 0) {
    return `${endpointClusterName}/${toHex(commandId)}`;
  }
  const command = getClusterCommandById(getClusterById(clusterId), commandId);
  if (command === void 0) {
    return `${endpointClusterName}/unknown(${toHex(commandId)})`;
  }
  return `${endpointClusterName}/${command.name}(${toHex(commandId)})`;
}
export {
  UnknownCluster,
  getClusterAttributeById,
  getClusterById,
  getClusterCommandById,
  getClusterEventById,
  getClusterNameById,
  resolveAttributeName,
  resolveCommandName,
  resolveEventName
};
//# sourceMappingURL=ClusterHelper.js.map
