"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 ClusterBehavior_exports = {};
__export(ClusterBehavior_exports, {
  ClusterBehavior: () => ClusterBehavior
});
module.exports = __toCommonJS(ClusterBehavior_exports);
var import_Events = require("#behavior/Events.js");
var import_general = require("#general");
var import_model = require("#model");
var import_types = require("#types");
var import_Behavior = require("../Behavior.js");
var import_NetworkBehavior = require("../system/network/NetworkBehavior.js");
var import_cluster_behavior_utils = require("./cluster-behavior-utils.js");
var import_ClusterBehaviorType = require("./ClusterBehaviorType.js");
var import_ClusterInterface = require("./ClusterInterface.js");
/**
 * @license
 * Copyright 2022-2025 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
class ClusterBehavior extends import_Behavior.Behavior {
  /**
   * The ID of ClusterBehavior implementations is the uncapitalized cluster name.
   */
  static id;
  /**
   * The cluster implemented by this behavior.
   */
  get cluster() {
    return this.constructor.cluster;
  }
  /**
   * Supported features as a flag object.
   */
  get features() {
    return this.cluster.supportedFeatures;
  }
  get type() {
    return this.constructor;
  }
  /**
   * Every cluster behavior has an associated ClusterType defined statically.
   */
  static cluster = import_types.ClusterType.Unknown;
  /**
   * Method definitions.
   */
  static Interface = import_ClusterInterface.ClusterInterface.Empty;
  /**
   * All ClusterBehavior initialization currently runs as part of {@link Endpoint} initialization.
   */
  static early = true;
  /**
   * Keep networking alive until I'm destroyed.
   */
  static dependencies = [import_NetworkBehavior.NetworkBehavior];
  /**
   * Automatically lock state on command invoke.
   */
  static lockOnInvoke = true;
  constructor(agent, backing) {
    super(agent, backing);
    const cluster = this.constructor.cluster;
    if (!cluster) {
      throw new import_general.ImplementationError("ClusterBehavior class has no cluster defined");
    }
  }
  /**
   * Create a new behavior for a specific {@link ClusterType}.
   *
   * If you invoke directly on {@link ClusterBehavior} you will receive a new implementation that reports all commands
   * as unimplemented.
   *
   * If you invoke on an existing subclass, you will receive a new implementation with the cluster in the subclass
   * replaced.  You should generally only do this with a {@link ClusterType} with the same ID.
   */
  static for(cluster, schema, name) {
    return (0, import_ClusterBehaviorType.ClusterBehaviorType)({
      cluster,
      base: this,
      schema,
      name
    });
  }
  /**
   * Create a new behavior with different cluster features.
   */
  static withFeatures(...features) {
    const newCluster = new import_types.ClusterComposer(this.cluster).compose(features);
    return this.for(newCluster);
  }
  /**
   * Alias for {@link withFeatures}.
   */
  static with(...features) {
    return this.withFeatures(...features);
  }
  /**
   * Create a new behavior with modified cluster elements.
   */
  static alter(alterations) {
    const cluster = new import_types.ClusterTypeModifier(this.cluster).alter(alterations);
    const schema = import_model.ClusterModifier.applyRequirements(this.schema, alterations);
    return this.for(cluster, schema);
  }
  /**
   * Create a new behavior with additional cluster features marked "mandatory".
   *
   * This informs matter.js that an application supports these elements.
   */
  static enable(flags) {
    const cluster = new import_types.ClusterTypeModifier(this.cluster).enable(flags);
    const schema = import_model.ClusterModifier.applyPresence(this.schema, flags);
    return this.for(cluster, schema);
  }
  /**
   * Create a ClusterBehavior like this one with different interface methods.
   *
   * The Interface "property" is type-only.  We define a method however to keep the API consistent.  At runtime the
   * method is a no-op.
   */
  static withInterface() {
    return this;
  }
  static supports(other) {
    const otherCluster = other.cluster;
    if (!otherCluster) {
      return false;
    }
    if ((0, import_cluster_behavior_utils.isClientBehavior)(other) && otherCluster.id === this.cluster.id) {
      return true;
    }
    if (!import_Behavior.Behavior.supports.call(this, other)) {
      return false;
    }
    const otherFeatures = otherCluster.supportedFeatures;
    const myFeatures = this.cluster.supportedFeatures;
    for (const name in otherFeatures) {
      if (otherFeatures[name] && !myFeatures[name]) {
        return false;
      }
    }
    return true;
  }
  requireAttributeEnabled(attributeName) {
    if (this.state[attributeName] === void 0) {
      throw new import_general.ImplementationError(
        `To use this feature, please enable attribute ${String(attributeName)} by setting the value during initialization`
      );
    }
    return this.state[attributeName];
  }
  assertAttributeEnabled(attributeName) {
    if (this.state[attributeName] === void 0) {
      throw new import_general.ImplementationError(
        `To use this feature, please enable attribute ${String(attributeName)} by setting the value during initialization`
      );
    }
  }
  static Events = import_Events.Events;
}
((ClusterBehavior2) => {
  function is(type) {
    return "cluster" in type;
  }
  ClusterBehavior2.is = is;
})(ClusterBehavior || (ClusterBehavior = {}));
//# sourceMappingURL=ClusterBehavior.js.map
