/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { MutableCluster } from "../cluster/mutation/MutableCluster.js";
import { Attribute, OptionalAttribute, Command } from "../cluster/Cluster.js";
import { TlvArray } from "../tlv/TlvArray.js";
import { TlvUInt16, TlvEnum } from "../tlv/TlvNumber.js";
import { BitFlag } from "../schema/BitmapSchema.js";
import { TlvField, TlvObject, TlvOptionalField } from "../tlv/TlvObject.js";
import { TlvString, TlvByteString } from "../tlv/TlvString.js";
import { TlvEndpointNumber } from "../datatype/EndpointNumber.js";
import { TlvNullable } from "../tlv/TlvNullable.js";
import { StatusResponseError } from "../common/StatusResponseError.js";
import { Status as GlobalStatus } from "../globals/Status.js";
import { ClusterRegistry } from "../cluster/ClusterRegistry.js";
var ApplicationLauncher;
((ApplicationLauncher2) => {
  let Feature;
  ((Feature2) => {
    Feature2["ApplicationPlatform"] = "ApplicationPlatform";
  })(Feature = ApplicationLauncher2.Feature || (ApplicationLauncher2.Feature = {}));
  ApplicationLauncher2.TlvApplication = TlvObject({
    /**
     * This field shall indicate the Connectivity Standards Alliance-issued vendor ID for the catalog. The DIAL
     * registry shall use value 0x0000.
     *
     * Content App Platform providers will have their own catalog vendor ID (set to their own Vendor ID) and will
     * assign an ApplicationID to each Content App.
     *
     * @see {@link MatterSpecification.v142.Cluster} § 6.4.5.2.1
     */
    catalogVendorId: TlvField(0, TlvUInt16),
    /**
     * This field shall indicate the application identifier, expressed as a string, such as "PruneVideo" or "Company
     * X". This field shall be unique within a catalog.
     *
     * For the DIAL registry catalog, this value shall be the DIAL prefix (see [DIAL Registry]).
     *
     * @see {@link MatterSpecification.v142.Cluster} § 6.4.5.2.2
     */
    applicationId: TlvField(1, TlvString)
  });
  ApplicationLauncher2.TlvApplicationEp = TlvObject({
    application: TlvField(0, ApplicationLauncher2.TlvApplication),
    endpoint: TlvOptionalField(1, TlvEndpointNumber)
  });
  ApplicationLauncher2.TlvLaunchAppRequest = TlvObject({
    /**
     * This field shall specify the Application to launch.
     *
     * @see {@link MatterSpecification.v142.Cluster} § 6.4.7.1.1
     */
    application: TlvOptionalField(0, ApplicationLauncher2.TlvApplication),
    /**
     * This field shall specify optional app-specific data to be sent to the app.
     *
     * > [!NOTE]
     *
     * > This format and meaning of this value is proprietary and outside the specification. It provides a
     *   transition path for device makers that use other protocols (like DIAL) which allow for proprietary data.
     *   Apps that are not yet Matter aware can be launched via Matter, while retaining the existing ability to
     *   launch with proprietary data.
     *
     * @see {@link MatterSpecification.v142.Cluster} § 6.4.7.1.2
     */
    data: TlvOptionalField(1, TlvByteString)
  });
  let Status;
  ((Status2) => {
    Status2[Status2["Success"] = 0] = "Success";
    Status2[Status2["AppNotAvailable"] = 1] = "AppNotAvailable";
    Status2[Status2["SystemBusy"] = 2] = "SystemBusy";
    Status2[Status2["PendingUserApproval"] = 3] = "PendingUserApproval";
    Status2[Status2["Downloading"] = 4] = "Downloading";
    Status2[Status2["Installing"] = 5] = "Installing";
  })(Status = ApplicationLauncher2.Status || (ApplicationLauncher2.Status = {}));
  class AppNotAvailableError extends StatusResponseError {
    constructor(message = "Requested app is not available", code = GlobalStatus.Failure, clusterCode = 1 /* AppNotAvailable */) {
      super(message, code, clusterCode);
    }
  }
  ApplicationLauncher2.AppNotAvailableError = AppNotAvailableError;
  class SystemBusyError extends StatusResponseError {
    constructor(message = "Video platform unable to honor command", code = GlobalStatus.Failure, clusterCode = 2 /* SystemBusy */) {
      super(message, code, clusterCode);
    }
  }
  ApplicationLauncher2.SystemBusyError = SystemBusyError;
  class PendingUserApprovalError extends StatusResponseError {
    constructor(message = "User approval for app download is pending", code = GlobalStatus.Failure, clusterCode = 3 /* PendingUserApproval */) {
      super(message, code, clusterCode);
    }
  }
  ApplicationLauncher2.PendingUserApprovalError = PendingUserApprovalError;
  class DownloadingError extends StatusResponseError {
    constructor(message = "Downloading the requested app", code = GlobalStatus.Failure, clusterCode = 4 /* Downloading */) {
      super(message, code, clusterCode);
    }
  }
  ApplicationLauncher2.DownloadingError = DownloadingError;
  class InstallingError extends StatusResponseError {
    constructor(message = "Installing the requested app", code = GlobalStatus.Failure, clusterCode = 5 /* Installing */) {
      super(message, code, clusterCode);
    }
  }
  ApplicationLauncher2.InstallingError = InstallingError;
  ApplicationLauncher2.TlvLauncherResponse = TlvObject({
    /**
     * This field shall indicate the status of the command which resulted in this response.
     *
     * @see {@link MatterSpecification.v142.Cluster} § 6.4.7.4.1
     */
    status: TlvField(0, TlvEnum()),
    /**
     * This field shall specify Optional app-specific data.
     *
     * @see {@link MatterSpecification.v142.Cluster} § 6.4.7.4.2
     */
    data: TlvOptionalField(1, TlvByteString)
  });
  ApplicationLauncher2.TlvStopAppRequest = TlvObject({
    /**
     * This field shall specify the Application to stop.
     *
     * @see {@link MatterSpecification.v142.Cluster} § 6.4.7.2.1
     */
    application: TlvOptionalField(0, ApplicationLauncher2.TlvApplication)
  });
  ApplicationLauncher2.TlvHideAppRequest = TlvObject({
    /**
     * This field shall specify the Application to hide.
     *
     * @see {@link MatterSpecification.v142.Cluster} § 6.4.7.3.1
     */
    application: TlvOptionalField(0, ApplicationLauncher2.TlvApplication)
  });
  ApplicationLauncher2.ApplicationPlatformComponent = MutableCluster.Component({
    attributes: {
      /**
       * This attribute shall specify the list of supported application catalogs, where each entry in the list is
       * the Connectivity Standards Alliance-issued vendor ID for the catalog. The DIAL registry (see [DIAL
       * Registry]) shall use value 0x0000.
       *
       * It is expected that Content App Platform providers will have their own catalog vendor ID (set to their
       * own Vendor ID) and will assign an ApplicationID to each Content App.
       *
       * @see {@link MatterSpecification.v142.Cluster} § 6.4.6.1
       */
      catalogList: Attribute(0, TlvArray(TlvUInt16), { persistent: true, default: [] })
    }
  });
  ApplicationLauncher2.Base = MutableCluster.Component({
    id: 1292,
    name: "ApplicationLauncher",
    revision: 2,
    features: {
      /**
       * Support for attributes and commands required for endpoint to support launching any application within the
       * supported application catalogs
       */
      applicationPlatform: BitFlag(0)
    },
    attributes: {
      /**
       * This attribute shall specify the current in-focus application, identified using an Application ID,
       * catalog vendor ID and the corresponding endpoint number when the application is represented by a Content
       * App endpoint. A null shall be used to indicate there is no current in-focus application.
       *
       * @see {@link MatterSpecification.v142.Cluster} § 6.4.6.2
       */
      currentApp: OptionalAttribute(1, TlvNullable(ApplicationLauncher2.TlvApplicationEp), { default: null })
    },
    commands: {
      /**
       * Upon receipt of this command, the server shall launch the application with optional data. The application
       * shall be either
       *
       *   • the specified application, if the Application Platform feature is supported;
       *
       *   • otherwise the application corresponding to the endpoint.
       *
       * The endpoint shall launch and bring to foreground the requisite application if the application is not
       * already launched and in foreground. The Status attribute shall be updated to ActiveVisibleFocus on the
       * Application Basic cluster of the Endpoint corresponding to the launched application. The Status attribute
       * shall be updated on any other application whose Status may have changed as a result of this command. The
       * CurrentApp attribute, if supported, shall be updated to reflect the new application in the foreground.
       *
       * This command returns a Launcher Response.
       *
       * @see {@link MatterSpecification.v142.Cluster} § 6.4.7.1
       */
      launchApp: Command(0, ApplicationLauncher2.TlvLaunchAppRequest, 3, ApplicationLauncher2.TlvLauncherResponse),
      /**
       * Upon receipt of this command, the server shall stop the application if it is running. The application
       * shall be either
       *
       *   • the specified application, if the Application Platform feature is supported;
       *
       *   • otherwise the application corresponding to the endpoint.
       *
       * The Status attribute shall be updated to Stopped on the Application Basic cluster of the Endpoint
       * corresponding to the stopped application. The Status attribute shall be updated on any other application
       * whose Status may have changed as a result of this command.
       *
       * This command returns a Launcher Response.
       *
       * @see {@link MatterSpecification.v142.Cluster} § 6.4.7.2
       */
      stopApp: Command(1, ApplicationLauncher2.TlvStopAppRequest, 3, ApplicationLauncher2.TlvLauncherResponse),
      /**
       * Upon receipt of this command, the server shall hide the application. The application shall be either
       *
       *   • the specified application, if the Application Platform feature is supported;
       *
       *   • otherwise the application corresponding to the endpoint.
       *
       * The endpoint may decide to stop the application based on manufacturer specific behavior or resource
       * constraints if any. The Status attribute shall be updated to ActiveHidden or Stopped, depending on the
       * action taken, on the Application Basic cluster of the Endpoint corresponding to the application on which
       * the action was taken. The Status attribute shall be updated on any other application whose Status may
       * have changed as a result of this command.
       *
       * This command returns a Launcher Response.
       *
       * @see {@link MatterSpecification.v142.Cluster} § 6.4.7.3
       */
      hideApp: Command(2, ApplicationLauncher2.TlvHideAppRequest, 3, ApplicationLauncher2.TlvLauncherResponse)
    },
    /**
     * This metadata controls which ApplicationLauncherCluster elements matter.js activates for specific feature
     * combinations.
     */
    extensions: MutableCluster.Extensions(
      { flags: { applicationPlatform: true }, component: ApplicationLauncher2.ApplicationPlatformComponent }
    )
  });
  ApplicationLauncher2.ClusterInstance = MutableCluster(ApplicationLauncher2.Base);
  ApplicationLauncher2.Cluster = ApplicationLauncher2.ClusterInstance;
  const AP = { applicationPlatform: true };
  ApplicationLauncher2.CompleteInstance = MutableCluster({
    id: ApplicationLauncher2.Cluster.id,
    name: ApplicationLauncher2.Cluster.name,
    revision: ApplicationLauncher2.Cluster.revision,
    features: ApplicationLauncher2.Cluster.features,
    attributes: {
      ...ApplicationLauncher2.Cluster.attributes,
      catalogList: MutableCluster.AsConditional(
        ApplicationLauncher2.ApplicationPlatformComponent.attributes.catalogList,
        { mandatoryIf: [AP] }
      )
    },
    commands: ApplicationLauncher2.Cluster.commands
  });
  ApplicationLauncher2.Complete = ApplicationLauncher2.CompleteInstance;
})(ApplicationLauncher || (ApplicationLauncher = {}));
const ApplicationLauncherCluster = ApplicationLauncher.Cluster;
ClusterRegistry.register(ApplicationLauncher.Complete);
export {
  ApplicationLauncher,
  ApplicationLauncherCluster
};
//# sourceMappingURL=application-launcher.js.map
