/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { MutableCluster } from "../cluster/mutation/MutableCluster.js";
import {
  Command,
  TlvNoResponse,
  Event,
  OptionalFixedAttribute,
  OptionalWritableAttribute,
  Attribute,
  FixedAttribute,
  OptionalAttribute,
  OptionalEvent
} from "../cluster/Cluster.js";
import { TlvField, TlvObject } from "../tlv/TlvObject.js";
import { TlvUInt32, TlvUInt16 } from "../tlv/TlvNumber.js";
import { Priority } from "../globals/Priority.js";
import { BitFlag } from "../schema/BitmapSchema.js";
import { TlvString } from "../tlv/TlvString.js";
import { TlvVendorId } from "../datatype/VendorId.js";
import { AccessLevel } from "#model";
import { TlvBoolean } from "../tlv/TlvBoolean.js";
import { BasicInformation } from "./basic-information.js";
import { TlvNoArguments } from "../tlv/TlvNoArguments.js";
import { ClusterRegistry } from "../cluster/ClusterRegistry.js";
var BridgedDeviceBasicInformation;
((BridgedDeviceBasicInformation2) => {
  let Feature;
  ((Feature2) => {
    Feature2["BridgedIcdSupport"] = "BridgedIcdSupport";
  })(Feature = BridgedDeviceBasicInformation2.Feature || (BridgedDeviceBasicInformation2.Feature = {}));
  BridgedDeviceBasicInformation2.TlvKeepActiveRequest = TlvObject({
    /**
     * This field shall indicate the duration, in milliseconds, that the device is requested to remain active, once
     * the device becomes active again.
     *
     * The value of this field may be longer than the value supported by the bridged device and would, typically, be
     * used by the client to request the server of the bridged device to stay active and responsive for this period
     * to allow a sequence of message exchanges during that period.
     *
     * The client may slightly overestimate the duration it wants the bridged device to be active for, in order to
     * account for network delays.
     *
     * @see {@link MatterSpecification.v142.Core} § 9.13.6.1.1
     */
    stayActiveDuration: TlvField(0, TlvUInt32),
    /**
     * This field shall indicate the period, in milliseconds, that the server will wait before the "pending active"
     * state expires. See the KeepActive Command description for details.
     *
     * > [!NOTE]
     *
     * > TimeoutMs is a timeout for the request, NOT the time the device will be awake for. The server will wait for
     *   up to TimeoutMs for the device. If after TimeoutMs the ICD device does NOT check-in, the server will not
     *   perform any actions.
     *
     * @see {@link MatterSpecification.v142.Core} § 9.13.6.1.2
     */
    timeoutMs: TlvField(1, TlvUInt32.bound({ min: 3e4, max: 36e5 }))
  });
  BridgedDeviceBasicInformation2.TlvActiveChangedEvent = TlvObject({
    /**
     * This field shall indicate the minimum duration, in milliseconds, that the bridged device will remain active
     * after receiving the initial request from the KeepActive processing steps.
     *
     * If the bridged device is a Matter Intermittently Connected Device, PromisedActiveDuration shall be set to the
     * PromisedActiveDuration value returned in the StayActiveResponse command.
     *
     * If the bridged device is not a Matter Intermittently Connected Device, the implementation of this is
     * best-effort since it may interact with non-native protocol.
     *
     * @see {@link MatterSpecification.v142.Core} § 9.13.7.3.1
     */
    promisedActiveDuration: TlvField(0, TlvUInt32)
  });
  BridgedDeviceBasicInformation2.TlvStartUpEvent = TlvObject({
    /**
     * This field shall be set to the same value as the one available in the SoftwareVersion attribute.
     *
     * @see {@link MatterSpecification.v142.Core} § 11.1.6.1.1
     */
    softwareVersion: TlvField(0, TlvUInt32)
  });
  BridgedDeviceBasicInformation2.TlvReachableChangedEvent = TlvObject({
    /**
     * This field shall indicate the value of the Reachable attribute after it was changed.
     *
     * @see {@link MatterSpecification.v142.Core} § 11.1.6.4.1
     */
    reachableNewValue: TlvField(0, TlvBoolean)
  });
  BridgedDeviceBasicInformation2.BridgedIcdSupportComponent = MutableCluster.Component({
    commands: {
      /**
       * Upon receipt, the server shall attempt to keep the bridged device active for the duration specified by
       * the command, when the device is next active.
       *
       * The implementation of this is best-effort since it may interact with non-native protocols. However,
       * several specific protocol requirements are:
       *
       *   - If the bridged device is a Matter Intermittently Connected Device, then the server shall send a
       *     StayActiveRequest command with the StayActiveDuration field set to value of the StayActiveDuration
       *     field in the received command to the bridged device when the bridged device next sends a checks-in
       *     message or subscription report. See Intermittently Connected Devices Behavior for details on ICD
       *     state management.
       *
       * When the bridge detects that the bridged device goes into an active state, an ActiveChanged event shall
       * be generated.
       *
       * In order to avoid unnecessary power consumption in the bridged device:
       *
       *   - The server shall enter a "pending active" state for the associated device when the KeepActive command
       *     is received. The server "pending active" state shall expire after the amount of time defined by the
       *     TimeoutMs field, in milliseconds, if no subsequent KeepActive command is received. When a KeepActive
       *     command is received, the "pending active" state is set, the StayActiveDuration is updated to the
       *     greater of the new value and the previously stored value, and the TimeoutMs is updated to the greater
       *     of the new value and the remaining time until the prior "pending active" state expires.
       *
       *   - The server shall only keep the bridged device active once for a request. (The server shall only
       *     consider the operation performed if an associated ActiveChanged event was generated.)
       *
       * @see {@link MatterSpecification.v142.Core} § 9.13.6.1
       */
      keepActive: Command(128, BridgedDeviceBasicInformation2.TlvKeepActiveRequest, 128, TlvNoResponse)
    },
    events: {
      /**
       * This event (when supported) shall be generated the next time a bridged device becomes active after a
       * KeepActive command is received. See KeepActive for more details.
       *
       * @see {@link MatterSpecification.v142.Core} § 9.13.7.3
       */
      activeChanged: Event(128, Priority.Info, BridgedDeviceBasicInformation2.TlvActiveChangedEvent)
    }
  });
  BridgedDeviceBasicInformation2.Base = MutableCluster.Component({
    id: 57,
    name: "BridgedDeviceBasicInformation",
    revision: 5,
    features: {
      /**
       * Support bridged ICDs.
       */
      bridgedIcdSupport: BitFlag(20)
    },
    attributes: {
      /**
       * @see {@link MatterSpecification.v142.Core} § 9.13.5
       */
      vendorName: OptionalFixedAttribute(1, TlvString.bound({ maxLength: 32 })),
      /**
       * @see {@link MatterSpecification.v142.Core} § 9.13.5
       */
      vendorId: OptionalFixedAttribute(2, TlvVendorId),
      /**
       * @see {@link MatterSpecification.v142.Core} § 9.13.5
       */
      productName: OptionalFixedAttribute(3, TlvString.bound({ maxLength: 32 })),
      /**
       * @see {@link MatterSpecification.v142.Core} § 9.13.5
       */
      productId: OptionalFixedAttribute(4, TlvUInt16),
      /**
       * @see {@link MatterSpecification.v142.Core} § 9.13.5
       */
      nodeLabel: OptionalWritableAttribute(
        5,
        TlvString.bound({ maxLength: 32 }),
        { persistent: true, writeAcl: AccessLevel.Manage }
      ),
      /**
       * @see {@link MatterSpecification.v142.Core} § 9.13.5
       */
      hardwareVersion: OptionalFixedAttribute(7, TlvUInt16),
      /**
       * @see {@link MatterSpecification.v142.Core} § 9.13.5
       */
      hardwareVersionString: OptionalFixedAttribute(8, TlvString.bound({ minLength: 1, maxLength: 64 })),
      /**
       * @see {@link MatterSpecification.v142.Core} § 9.13.5
       */
      softwareVersion: OptionalFixedAttribute(9, TlvUInt32),
      /**
       * @see {@link MatterSpecification.v142.Core} § 9.13.5
       */
      softwareVersionString: OptionalFixedAttribute(10, TlvString.bound({ minLength: 1, maxLength: 64 })),
      /**
       * @see {@link MatterSpecification.v142.Core} § 9.13.5
       */
      manufacturingDate: OptionalFixedAttribute(11, TlvString.bound({ minLength: 8, maxLength: 16 })),
      /**
       * @see {@link MatterSpecification.v142.Core} § 9.13.5
       */
      partNumber: OptionalFixedAttribute(12, TlvString.bound({ maxLength: 32 })),
      /**
       * @see {@link MatterSpecification.v142.Core} § 9.13.5
       */
      productUrl: OptionalFixedAttribute(13, TlvString.bound({ maxLength: 256 })),
      /**
       * @see {@link MatterSpecification.v142.Core} § 9.13.5
       */
      productLabel: OptionalFixedAttribute(14, TlvString.bound({ maxLength: 64 })),
      /**
       * @see {@link MatterSpecification.v142.Core} § 9.13.5
       */
      serialNumber: OptionalFixedAttribute(15, TlvString.bound({ maxLength: 32 })),
      /**
       * This attribute shall be used to indicate whether the bridged device is reachable by the bridge, so a
       * Matter Node which wants to communicate with a bridged device can get an indication that this might fail
       * (when the attribute is False). Determination of reachability might not be perfect (e.g. depending on
       * technology employed), so the Matter Node SHOULD be aware of the risk of false positives and negatives on
       * reachability determination. For example, a bridged device may be marked as unreachable while it could
       * actually be reached, and vice-versa. Also, detection (and indication) that a bridged device is not longer
       * reachable may be delayed due to the technique employed (e.g. detecting that a number of expected messages
       * from the bridged device did not arrive). Also see event ReachableChanged below.
       *
       * @see {@link MatterSpecification.v142.Core} § 9.13.5.2
       */
      reachable: Attribute(17, TlvBoolean),
      /**
       * This attribute shall, for a Bridged Device, be updated when the Bridge is factory reset. If the bridged
       * device does not provide some unique id (e.g. in the case of bridging from non-Matter devices, or in case
       * of bridging Matter devices from an earlier revision which were not required to provide a UniqueID
       * attribute), the bridge shall generate a unique id on behalf of the bridged device.
       *
       * > [!NOTE]
       *
       * > The UniqueID attribute was optional in cluster revisions prior to revision 4.
       *
       * @see {@link MatterSpecification.v142.Core} § 9.13.5.3
       */
      uniqueId: FixedAttribute(18, TlvString.bound({ maxLength: 32 })),
      /**
       * @see {@link MatterSpecification.v142.Core} § 9.13.5
       */
      productAppearance: OptionalFixedAttribute(20, BasicInformation.TlvProductAppearance),
      /**
       * This attribute shall contain the current version number for the configuration of the bridged device.
       *
       * If the bridge detects a change on a bridged device, which it deems as a change in the configuration of
       * the bridged device, it shall increase this attribute as described in Section 9.2.9, “Node Configuration
       * Changes”.
       *
       * The ability and the method used to detect such a change on a bridged device is manufacturer specific.
       *
       * @see {@link MatterSpecification.v142.Core} § 9.13.5.4
       */
      configurationVersion: OptionalAttribute(24, TlvUInt32.bound({ min: 1 }), { persistent: true })
    },
    events: {
      /**
       * @see {@link MatterSpecification.v142.Core} § 9.13.7
       */
      startUp: OptionalEvent(0, Priority.Critical, BridgedDeviceBasicInformation2.TlvStartUpEvent),
      /**
       * @see {@link MatterSpecification.v142.Core} § 9.13.7
       */
      shutDown: OptionalEvent(1, Priority.Critical, TlvNoArguments),
      /**
       * The Leave event SHOULD be generated by the bridge when it detects that the associated device has left the
       * non-Matter network.
       *
       * > [!NOTE]
       *
       * > The FabricIndex field has the X conformance, indicating it shall NOT be present. This event, in the
       *   context of Bridged Device Basic Information cluster, has no usable fields, but the original Basic
       *   Information cluster’s field definition is kept for completeness.
       *
       * @see {@link MatterSpecification.v142.Core} § 9.13.7.1
       */
      leave: OptionalEvent(2, Priority.Critical, TlvNoArguments),
      /**
       * This event shall be generated when there is a change in the Reachable attribute. Its purpose is to
       * provide an indication towards interested parties that the reachability of a bridged device has changed
       * over its native connectivity technology, so they may take appropriate action. After (re)start of a bridge
       * this event may be generated.
       *
       * @see {@link MatterSpecification.v142.Core} § 9.13.7.2
       */
      reachableChanged: Event(3, Priority.Critical, BridgedDeviceBasicInformation2.TlvReachableChangedEvent)
    },
    /**
     * This metadata controls which BridgedDeviceBasicInformationCluster elements matter.js activates for specific
     * feature combinations.
     */
    extensions: MutableCluster.Extensions(
      { flags: { bridgedIcdSupport: true }, component: BridgedDeviceBasicInformation2.BridgedIcdSupportComponent }
    )
  });
  BridgedDeviceBasicInformation2.ClusterInstance = MutableCluster(BridgedDeviceBasicInformation2.Base);
  BridgedDeviceBasicInformation2.Cluster = BridgedDeviceBasicInformation2.ClusterInstance;
  const BIS = { bridgedIcdSupport: true };
  BridgedDeviceBasicInformation2.CompleteInstance = MutableCluster({
    id: BridgedDeviceBasicInformation2.Cluster.id,
    name: BridgedDeviceBasicInformation2.Cluster.name,
    revision: BridgedDeviceBasicInformation2.Cluster.revision,
    features: BridgedDeviceBasicInformation2.Cluster.features,
    attributes: BridgedDeviceBasicInformation2.Cluster.attributes,
    commands: {
      keepActive: MutableCluster.AsConditional(
        BridgedDeviceBasicInformation2.BridgedIcdSupportComponent.commands.keepActive,
        { mandatoryIf: [BIS] }
      )
    },
    events: {
      ...BridgedDeviceBasicInformation2.Cluster.events,
      activeChanged: MutableCluster.AsConditional(
        BridgedDeviceBasicInformation2.BridgedIcdSupportComponent.events.activeChanged,
        { mandatoryIf: [BIS] }
      )
    }
  });
  BridgedDeviceBasicInformation2.Complete = BridgedDeviceBasicInformation2.CompleteInstance;
})(BridgedDeviceBasicInformation || (BridgedDeviceBasicInformation = {}));
const BridgedDeviceBasicInformationCluster = BridgedDeviceBasicInformation.Cluster;
ClusterRegistry.register(BridgedDeviceBasicInformation.Complete);
export {
  BridgedDeviceBasicInformation,
  BridgedDeviceBasicInformationCluster
};
//# sourceMappingURL=bridged-device-basic-information.js.map
