"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 GroupsServer_exports = {};
__export(GroupsServer_exports, {
  GroupsServer: () => GroupsServer
});
module.exports = __toCommonJS(GroupsServer_exports);
var import_group_key_management = require("#behaviors/group-key-management");
var import_identify = require("#behaviors/identify");
var import_scenes_management = require("#behaviors/scenes-management");
var import_root = require("#endpoints/root");
var import_general = require("@matter/general");
var import_model = require("@matter/model");
var import_protocol = require("@matter/protocol");
var import_types = require("@matter/types");
var import_groups = require("@matter/types/clusters/groups");
var import_GroupsBehavior = require("./GroupsBehavior.js");
/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
const logger = import_general.Logger.get("GroupsServer");
import_groups.Groups.Cluster.commands = {
  ...import_groups.Groups.Cluster.commands,
  addGroup: (0, import_types.Command)(
    0,
    (0, import_types.TlvObject)({
      groupId: (0, import_types.TlvField)(0, import_types.TlvGroupId),
      groupName: (0, import_types.TlvField)(1, import_types.TlvString)
    }),
    0,
    import_groups.Groups.TlvAddGroupResponse,
    { invokeAcl: import_model.AccessLevel.Manage }
  ),
  addGroupIfIdentifying: (0, import_types.Command)(
    5,
    (0, import_types.TlvObject)({
      groupId: (0, import_types.TlvField)(0, import_types.TlvGroupId),
      groupName: (0, import_types.TlvField)(1, import_types.TlvString)
    }),
    5,
    import_types.TlvNoResponse,
    { invokeAcl: import_model.AccessLevel.Manage }
  )
};
const GroupsBase = import_GroupsBehavior.GroupsBehavior.with(import_groups.Groups.Feature.GroupNames);
class GroupsServer extends GroupsBase {
  initialize() {
    this.state.nameSupport.groupNames = this.features.groupNames;
  }
  // We need to search the root here ourselves because we cannot include ServerNode because else we generate a
  // circular dependency
  get #rootEndpoint() {
    const rootEndpoint = this.endpoint.ownerOfType(import_root.RootEndpoint);
    if (rootEndpoint === void 0) {
      throw new import_general.InternalError("RootEndpoint not found");
    }
    return rootEndpoint;
  }
  async #actOnGroupKeyManagement(act) {
    (0, import_protocol.assertRemoteActor)(this.context);
    const agent = this.#rootEndpoint.agentFor(this.context);
    const gkm = agent.get(import_group_key_management.GroupKeyManagementServer);
    await agent.context.transaction.addResources(gkm);
    await agent.context.transaction.begin();
    return act(this.context.session.associatedFabric, gkm);
  }
  async addGroup({ groupId, groupName }) {
    (0, import_protocol.assertRemoteActor)(this.context);
    const fabric = this.context.session.associatedFabric;
    if (groupId < 1) {
      return { status: import_types.StatusCode.ConstraintError, groupId };
    }
    if (groupName.length > 16) {
      return { status: import_types.StatusCode.ConstraintError, groupId };
    }
    if (!fabric.groups.groupKeyIdMap.has(groupId)) {
      return { status: import_types.StatusCode.UnsupportedAccess, groupId };
    }
    const endpointNumber = this.endpoint.number;
    try {
      await this.#actOnGroupKeyManagement(
        (fabric2, gkm) => gkm.addEndpointForGroup(fabric2, groupId, endpointNumber, groupName)
      );
    } catch (error) {
      logger.error(error);
      import_types.StatusResponseError.accept(error);
      return { status: error.code, groupId };
    }
    return { status: import_types.StatusCode.Success, groupId };
  }
  viewGroup({ groupId }) {
    (0, import_protocol.assertRemoteActor)(this.context);
    const fabric = this.context.session.associatedFabric;
    if (groupId < 1) {
      return { status: import_types.StatusCode.ConstraintError, groupId, groupName: "" };
    }
    const fabricIndex = fabric.fabricIndex;
    const endpointNumber = this.endpoint.number;
    const { groupTable } = this.#rootEndpoint.stateOf(import_group_key_management.GroupKeyManagementServer);
    const groupEntry = groupTable.find((entry) => entry.groupId === groupId && entry.fabricIndex === fabricIndex);
    if (groupEntry === void 0 || !groupEntry.endpoints.includes(endpointNumber)) {
      return { status: import_types.StatusCode.NotFound, groupId, groupName: "" };
    }
    return { status: import_types.StatusCode.Success, groupId, groupName: groupEntry.groupName ?? "" };
  }
  async getGroupMembership({
    groupList
  }) {
    (0, import_protocol.assertRemoteActor)(this.context);
    const fabric = this.context.session.associatedFabric;
    const fabricIndex = fabric.fabricIndex;
    const endpointNumber = this.endpoint.number;
    const { groupTable } = this.#rootEndpoint.stateOf(import_group_key_management.GroupKeyManagementServer);
    const endpointGroups = groupTable.filter(
      (entry) => entry.endpoints.includes(endpointNumber) && entry.fabricIndex === fabricIndex
    );
    const fabricGroupsList = endpointGroups.map((entry) => entry.groupId);
    if (groupList.length === 0) {
      return { capacity: 254 - fabricGroupsList.length, groupList: fabricGroupsList };
    }
    const filteredGroupsList = groupList.filter((groupId) => fabricGroupsList.includes(groupId));
    return { capacity: 254 - fabricGroupsList.length, groupList: filteredGroupsList };
  }
  async removeGroup({ groupId }) {
    if (groupId < 1) {
      return { status: import_types.StatusCode.ConstraintError, groupId };
    }
    try {
      (0, import_protocol.assertRemoteActor)(this.context);
      if (await this.#actOnGroupKeyManagement(
        (fabric, gkm) => gkm.removeEndpoint(fabric, this.endpoint.number, groupId)
      )) {
        if (this.agent.has(import_scenes_management.ScenesManagementServer)) {
          this.agent.get(import_scenes_management.ScenesManagementServer).removeScenesForGroupOnFabric(this.context.session.associatedFabric.fabricIndex, groupId);
        }
        return { status: import_types.StatusCode.Success, groupId };
      }
      return { status: import_types.StatusCode.NotFound, groupId };
    } catch (error) {
      import_types.StatusResponseError.accept(error);
      return { status: error.code, groupId };
    }
  }
  async removeAllGroups() {
    try {
      (0, import_protocol.assertRemoteActor)(this.context);
      await this.#actOnGroupKeyManagement((fabric, gkm) => gkm.removeEndpoint(fabric, this.endpoint.number));
      if (this.agent.has(import_scenes_management.ScenesManagementServer)) {
        this.agent.get(import_scenes_management.ScenesManagementServer).removeScenesForAllGroupsForFabric(this.context.session.associatedFabric.fabricIndex);
      }
    } catch (error) {
      import_types.StatusResponseError.accept(error);
      throw error;
    }
  }
  async addGroupIfIdentifying({ groupId, groupName }) {
    if (this.endpoint.stateOf(import_identify.IdentifyBehavior).identifyTime > 0) {
      const { status } = await this.addGroup({ groupId, groupName });
      if (status !== import_types.StatusCode.Success) {
        throw new import_types.StatusResponseError(`Failed to add group ${groupId}`, status);
      }
    }
  }
}
//# sourceMappingURL=GroupsServer.js.map
