/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { NamedHandler, NotImplementedError } from "@matter/general";
import { RootNodeDt } from "@matter/model";
import { EndpointNumber } from "@matter/types";
import { DeviceClasses, getDeviceTypeDefinitionFromModelByCode } from "./DeviceTypes.js";
import { Endpoint } from "./Endpoint.js";
class PairedDevice extends Endpoint {
  /**
   * Create a new PairedDevice instance. All data are automatically parsed from the paired device!
   *
   * @param endpoint Underlying ClientEndpoint instance
   * @param definition DeviceTypeDefinitions of the paired device as reported by the device
   * @param clusters Clusters of the paired device as reported by the device
   * @param endpointId Endpoint ID of the paired device as reported by the device
   */
  constructor(endpoint, definition, clusters = [], endpointId) {
    super(endpoint, definition, { endpointId });
    clusters.forEach((cluster) => {
      this.addClusterClient(cluster);
    });
  }
}
class RootEndpoint extends Endpoint {
  /**
   * Create a new RootEndpoint instance. This is automatically instanced by the CommissioningServer class.
   */
  constructor(endpoint) {
    super(endpoint, [getDeviceTypeDefinitionFromModelByCode(RootNodeDt.id)], { endpointId: EndpointNumber(0) });
  }
  /**
   * Add a cluster client to the root endpoint. This is mainly used internally and not needed to be called by the user.
   *
   * @param cluster ClusterClient object to add
   */
  addRootClusterClient(cluster) {
    this.addClusterClient(cluster);
  }
  getRootClusterClient(cluster) {
    return this.getClusterClient(cluster);
  }
}
class Device extends Endpoint {
  commandHandler = new NamedHandler();
  /**
   * Create a new Device instance.
   *
   * @param endpoint Underlying ClientEndpoint instance
   * @param definition DeviceTypeDefinitions of the device
   * @param options Optional endpoint options
   */
  constructor(endpoint, definition, options = {}) {
    if (definition.deviceClass === DeviceClasses.Node) {
      throw new NotImplementedError("MatterNode devices are not supported");
    }
    super(endpoint, [definition], options);
  }
  /**
   * Method to add command handlers to the device.
   * The base class do not expose any commands!
   *
   * @param command Command name to add a handler for
   * @param handler Handler function to be executed when the command is received
   */
  addCommandHandler(command, handler) {
    this.commandHandler.addHandler(command, handler);
  }
  /**
   * Method to remove command handlers from the device.
   * The base class do not expose any commands!
   *
   * @param command Command name to remove the handler from
   * @param handler Handler function to be removed
   */
  removeCommandHandler(command, handler) {
    this.commandHandler.removeHandler(command, handler);
  }
  /**
   * Execute a command handler. Should only be used internally, but cannot be declared as protected officially
   * because needed public for derived classes.
   *
   * @protected
   * @param command Command name to execute the handler for
   * @param args Arguments to be passed to the handler
   */
  async _executeHandler(command, ...args) {
    return await this.commandHandler.executeHandler(command, ...args);
  }
}
export {
  Device,
  PairedDevice,
  RootEndpoint
};
//# sourceMappingURL=Device.js.map
