/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { MatterError, Merge } from "#general";
import { Priority } from "#globals/Priority.js";
import { AccessLevel } from "#model";
import { AttributeId, TlvAttributeId } from "../datatype/AttributeId.js";
import { ClusterId } from "../datatype/ClusterId.js";
import { CommandId, TlvCommandId } from "../datatype/CommandId.js";
import { EventId } from "../datatype/EventId.js";
import { TlvAny } from "../tlv/TlvAny.js";
import { TlvArray } from "../tlv/TlvArray.js";
import { TlvBitmap, TlvUInt16, TlvUInt32 } from "../tlv/TlvNumber.js";
import { TlvVoid } from "../tlv/TlvVoid.js";
class AttributeError extends MatterError {
}
class EventError extends MatterError {
}
const Attribute = (id, schema, {
  scene = false,
  persistent = false,
  omitChanges = false,
  default: conformanceValue,
  readAcl = AccessLevel.View,
  timed = false
} = {}) => ({
  id: AttributeId(id),
  schema,
  optional: false,
  writable: false,
  fixed: false,
  scene,
  persistent,
  timed,
  fabricScoped: false,
  omitChanges,
  default: conformanceValue,
  readAcl,
  isConditional: false,
  optionalIf: [],
  mandatoryIf: [],
  unknown: false
});
const OptionalAttribute = (id, schema, {
  scene = false,
  persistent = false,
  omitChanges = false,
  default: conformanceValue,
  readAcl = AccessLevel.View,
  timed = false
} = {}) => ({
  id: AttributeId(id),
  schema,
  optional: true,
  writable: false,
  fixed: false,
  scene,
  persistent,
  fabricScoped: false,
  omitChanges,
  default: conformanceValue,
  readAcl,
  timed,
  isConditional: false,
  optionalIf: [],
  mandatoryIf: [],
  unknown: false
});
const ConditionalAttribute = (id, schema, {
  scene = false,
  persistent = false,
  omitChanges = false,
  default: conformanceValue,
  readAcl = AccessLevel.View,
  optionalIf = [],
  mandatoryIf = [],
  timed = false
}) => ({
  id: AttributeId(id),
  schema,
  optional: true,
  writable: false,
  fixed: false,
  scene,
  persistent,
  fabricScoped: false,
  omitChanges,
  default: conformanceValue,
  readAcl,
  timed,
  isConditional: true,
  optionalIf,
  mandatoryIf,
  unknown: false
});
const WritableAttribute = (id, schema, {
  scene = false,
  persistent = true,
  omitChanges = false,
  default: conformanceValue,
  readAcl = AccessLevel.View,
  writeAcl = AccessLevel.View,
  timed = false
} = {}) => ({
  id: AttributeId(id),
  schema,
  optional: false,
  writable: true,
  fixed: false,
  scene,
  persistent,
  fabricScoped: false,
  omitChanges,
  default: conformanceValue,
  readAcl,
  timed,
  writeAcl,
  isConditional: false,
  optionalIf: [],
  mandatoryIf: [],
  unknown: false
});
const OptionalWritableAttribute = (id, schema, {
  scene = false,
  persistent = true,
  omitChanges = false,
  default: conformanceValue,
  readAcl = AccessLevel.View,
  writeAcl = AccessLevel.View,
  timed = false
} = {}) => ({
  id: AttributeId(id),
  schema,
  optional: true,
  writable: true,
  fixed: false,
  scene,
  persistent,
  fabricScoped: false,
  omitChanges,
  default: conformanceValue,
  readAcl,
  timed,
  writeAcl,
  isConditional: false,
  optionalIf: [],
  mandatoryIf: [],
  unknown: false
});
const ConditionalWritableAttribute = (id, schema, {
  scene = false,
  persistent = true,
  omitChanges = false,
  default: conformanceValue,
  readAcl = AccessLevel.View,
  writeAcl = AccessLevel.View,
  optionalIf = [],
  mandatoryIf = [],
  timed = false
}) => ({
  id: AttributeId(id),
  schema,
  optional: true,
  writable: true,
  fixed: false,
  scene,
  persistent,
  fabricScoped: false,
  omitChanges,
  default: conformanceValue,
  readAcl,
  timed,
  writeAcl,
  isConditional: true,
  optionalIf,
  mandatoryIf,
  unknown: false
});
const FabricScopedAttribute = (id, schema, {
  scene = false,
  persistent = true,
  omitChanges = false,
  default: conformanceValue,
  readAcl = AccessLevel.View,
  timed = false
} = {}) => ({
  id: AttributeId(id),
  schema,
  optional: false,
  writable: false,
  fixed: false,
  scene,
  persistent,
  fabricScoped: true,
  omitChanges,
  default: conformanceValue,
  readAcl,
  timed,
  isConditional: false,
  optionalIf: [],
  mandatoryIf: [],
  unknown: false
});
const WritableFabricScopedAttribute = (id, schema, {
  scene = false,
  persistent = true,
  omitChanges = false,
  default: conformanceValue,
  readAcl = AccessLevel.View,
  writeAcl = AccessLevel.View,
  timed = false
} = {}) => ({
  id: AttributeId(id),
  schema,
  optional: false,
  writable: true,
  fixed: false,
  scene,
  persistent,
  fabricScoped: true,
  omitChanges,
  default: conformanceValue,
  readAcl,
  timed,
  writeAcl,
  isConditional: false,
  optionalIf: [],
  mandatoryIf: [],
  unknown: false
});
const OptionalWritableFabricScopedAttribute = (id, schema, {
  scene = false,
  persistent = true,
  omitChanges = false,
  default: conformanceValue,
  readAcl = AccessLevel.View,
  writeAcl = AccessLevel.View,
  timed = false
} = {}) => ({
  id: AttributeId(id),
  schema,
  optional: true,
  writable: true,
  fixed: false,
  scene,
  persistent,
  fabricScoped: true,
  omitChanges,
  default: conformanceValue,
  readAcl,
  timed,
  writeAcl,
  isConditional: false,
  optionalIf: [],
  mandatoryIf: [],
  unknown: false
});
const ConditionalWritableFabricScopedAttribute = (id, schema, {
  scene = false,
  persistent = true,
  omitChanges = false,
  default: conformanceValue,
  readAcl = AccessLevel.View,
  writeAcl = AccessLevel.View,
  optionalIf = [],
  mandatoryIf = [],
  timed = false
} = {}) => ({
  id: AttributeId(id),
  schema,
  optional: true,
  writable: true,
  fixed: false,
  scene,
  persistent,
  fabricScoped: true,
  omitChanges,
  default: conformanceValue,
  readAcl,
  timed,
  writeAcl,
  isConditional: true,
  optionalIf,
  mandatoryIf,
  unknown: false
});
const FixedAttribute = (id, schema, {
  scene = false,
  persistent = false,
  omitChanges = false,
  default: conformanceValue,
  readAcl = AccessLevel.View,
  timed = false
} = {}) => ({
  id: AttributeId(id),
  schema,
  optional: false,
  writable: false,
  fixed: true,
  scene,
  persistent,
  fabricScoped: false,
  omitChanges,
  default: conformanceValue,
  readAcl,
  timed,
  isConditional: false,
  optionalIf: [],
  mandatoryIf: [],
  unknown: false
});
const WritableFixedAttribute = (id, schema, {
  scene = false,
  persistent = false,
  omitChanges = false,
  default: conformanceValue,
  readAcl = AccessLevel.View,
  timed = false
} = {}) => ({
  id: AttributeId(id),
  schema,
  optional: false,
  writable: true,
  fixed: true,
  scene,
  persistent,
  fabricScoped: false,
  omitChanges,
  default: conformanceValue,
  readAcl,
  timed,
  isConditional: false,
  optionalIf: [],
  mandatoryIf: [],
  unknown: false
});
const OptionalFixedAttribute = (id, schema, {
  scene = false,
  persistent = false,
  omitChanges = false,
  default: conformanceValue,
  readAcl = AccessLevel.View,
  timed = false
} = {}) => ({
  id: AttributeId(id),
  schema,
  optional: true,
  writable: false,
  fixed: true,
  scene,
  persistent,
  fabricScoped: false,
  omitChanges,
  default: conformanceValue,
  readAcl,
  timed,
  isConditional: false,
  optionalIf: [],
  mandatoryIf: [],
  unknown: false
});
const ConditionalFixedAttribute = (id, schema, {
  scene = false,
  persistent = false,
  omitChanges = false,
  default: conformanceValue,
  readAcl = AccessLevel.View,
  timed = false,
  optionalIf = [],
  mandatoryIf = []
}) => ({
  id: AttributeId(id),
  schema,
  optional: true,
  writable: false,
  fixed: true,
  scene,
  persistent,
  fabricScoped: false,
  omitChanges,
  default: conformanceValue,
  readAcl,
  timed,
  isConditional: true,
  optionalIf,
  mandatoryIf,
  unknown: false
});
const UnknownAttribute = (id) => ({
  id,
  schema: TlvAny,
  optional: false,
  writable: true,
  fixed: false,
  scene: false,
  persistent: false,
  fabricScoped: false,
  omitChanges: true,
  // We assume custom clusters do mot report values via subscription because we do not know it
  default: void 0,
  readAcl: AccessLevel.View,
  timed: false,
  isConditional: true,
  optionalIf: [],
  mandatoryIf: [],
  unknown: true
});
const TlvNoResponse = TlvVoid;
const Command = (requestId, requestSchema, responseId, responseSchema, { invokeAcl = AccessLevel.Operate, timed = false } = {}) => ({
  optional: false,
  requestId: CommandId(requestId),
  requestSchema,
  responseId: CommandId(responseId),
  responseSchema,
  invokeAcl,
  timed,
  isConditional: false,
  optionalIf: [],
  mandatoryIf: []
});
const OptionalCommand = (requestId, requestSchema, responseId, responseSchema, { invokeAcl = AccessLevel.Operate, timed = false } = {}) => ({
  optional: true,
  requestId: CommandId(requestId),
  requestSchema,
  responseId: CommandId(responseId),
  responseSchema,
  invokeAcl,
  timed,
  isConditional: false,
  optionalIf: [],
  mandatoryIf: []
});
const ConditionalCommand = (requestId, requestSchema, responseId, responseSchema, {
  invokeAcl = AccessLevel.Operate,
  timed = false,
  optionalIf = [],
  mandatoryIf = []
} = {}) => ({
  optional: true,
  requestId: CommandId(requestId),
  requestSchema,
  responseId: CommandId(responseId),
  responseSchema,
  invokeAcl,
  timed,
  isConditional: true,
  optionalIf,
  mandatoryIf
});
const UnknownCommand = (requestId, requestSchema, responseId, responseSchema, { invokeAcl = AccessLevel.Operate, timed = false } = {}) => ({
  optional: false,
  requestId,
  requestSchema,
  responseId,
  responseSchema,
  invokeAcl,
  timed,
  isConditional: false,
  optionalIf: [],
  mandatoryIf: []
});
const EventPriority = Priority;
const Event = (id, priority, schema, { readAcl = AccessLevel.View } = {}) => ({
  id: EventId(id),
  schema,
  priority,
  optional: false,
  isConditional: false,
  readAcl,
  optionalIf: [],
  mandatoryIf: [],
  unknown: false
});
const OptionalEvent = (id, priority, schema, { readAcl = AccessLevel.View } = {}) => ({
  id: EventId(id),
  schema,
  priority,
  optional: true,
  readAcl,
  isConditional: false,
  optionalIf: [],
  mandatoryIf: [],
  unknown: false
});
const ConditionalEvent = (id, priority, schema, { readAcl = AccessLevel.View, optionalIf = [], mandatoryIf = [] }) => ({
  id: EventId(id),
  schema,
  priority,
  optional: true,
  readAcl,
  isConditional: true,
  optionalIf,
  mandatoryIf,
  unknown: false
});
const UnknownEvent = (id) => ({
  id: EventId(id),
  schema: TlvVoid,
  priority: Priority.Debug,
  optional: false,
  readAcl: AccessLevel.View,
  isConditional: false,
  optionalIf: [],
  mandatoryIf: [],
  unknown: true
});
const GlobalAttributes = (features) => ({
  clusterRevision: Attribute(65533, TlvUInt16),
  featureMap: Attribute(65532, TlvBitmap(TlvUInt32, features)),
  attributeList: Attribute(65531, TlvArray(TlvAttributeId)),
  acceptedCommandList: Attribute(65529, TlvArray(TlvCommandId)),
  generatedCommandList: Attribute(65528, TlvArray(TlvCommandId))
});
const Cluster = ({
  id,
  name,
  revision,
  features = {},
  supportedFeatures = {},
  attributes = {},
  commands = {},
  events = {},
  unknown = false
}) => ({
  id: ClusterId(id),
  name,
  revision,
  features,
  supportedFeatures,
  commands,
  attributes: Merge(attributes, GlobalAttributes(features)),
  events,
  unknown
});
const ClusterExtend = ({
  id,
  name,
  revision,
  features,
  supportedFeatures,
  attributes,
  commands,
  events,
  unknown
}, {
  supportedFeatures: supportedFeaturesExtend,
  attributes: attributesExtend = {},
  commands: commandsExtend = {},
  events: eventsExtend = {}
}) => ({
  id,
  name,
  revision,
  features,
  supportedFeatures: Merge(supportedFeatures, supportedFeaturesExtend),
  attributes: Merge(attributes, attributesExtend),
  commands: Merge(commands, commandsExtend),
  events: Merge(events, eventsExtend),
  unknown
});
export {
  Attribute,
  AttributeError,
  Cluster,
  ClusterExtend,
  Command,
  ConditionalAttribute,
  ConditionalCommand,
  ConditionalEvent,
  ConditionalFixedAttribute,
  ConditionalWritableAttribute,
  ConditionalWritableFabricScopedAttribute,
  Event,
  EventError,
  EventPriority,
  FabricScopedAttribute,
  FixedAttribute,
  GlobalAttributes,
  OptionalAttribute,
  OptionalCommand,
  OptionalEvent,
  OptionalFixedAttribute,
  OptionalWritableAttribute,
  OptionalWritableFabricScopedAttribute,
  TlvNoResponse,
  UnknownAttribute,
  UnknownCommand,
  UnknownEvent,
  WritableAttribute,
  WritableFabricScopedAttribute,
  WritableFixedAttribute
};
//# sourceMappingURL=Cluster.js.map
