"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 Invoke_exports = {};
__export(Invoke_exports, {
  Invoke: () => Invoke
});
module.exports = __toCommonJS(Invoke_exports);
var import_general = require("#general");
var import_SessionParameters = require("#session/SessionParameters.js");
var import_types = require("#types");
var import_MalformedRequestError = require("./MalformedRequestError.js");
var import_Specifier = require("./Specifier.js");
/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
function Invoke(optionsOrData, ...commands) {
  if (optionsOrData === void 0) {
    throw new import_MalformedRequestError.MalformedRequestError(`Invocation requires at least one command`);
  }
  let options;
  if ("commands" in optionsOrData) {
    options = optionsOrData;
    commands = [...optionsOrData.commands, ...commands];
  } else {
    commands = [optionsOrData, ...commands];
    options = {};
  }
  const {
    interactionModelRevision = import_SessionParameters.SessionParameters.fallbacks.interactionModelRevision,
    suppressResponse = false,
    timeout,
    expectedProcessingTime,
    useExtendedFailSafeMessageResponseTimeout = false,
    skipValidation = false
  } = options;
  let timedRequest = !!options.timed || !!timeout;
  if (!commands?.length) {
    throw new import_MalformedRequestError.MalformedRequestError(`Invocation requires at least one command`);
  }
  if (commands.length > 1) {
    const commandRefs = /* @__PURE__ */ new Set();
    for (const { commandRef } of commands) {
      if (commandRef === void 0) {
        throw new import_MalformedRequestError.MalformedRequestError(`CommandRef required when invoking multiple commands`);
      }
      if (commandRefs.has(commandRef)) {
        throw new import_MalformedRequestError.MalformedRequestError(`Duplicate commandRef ${commandRef} in multiple command invoke`);
      }
      commandRefs.add(commandRef);
    }
  }
  const commandMap = /* @__PURE__ */ new Map();
  const invokeRequests = commands.map((cmd) => {
    const cmdData = Invoke.Command(cmd, skipValidation);
    if (options.timed !== false) {
      timedRequest ||= !!cmdData.timed;
    }
    commandMap.set(cmdData.commandRef, cmd);
    return cmdData;
  });
  return {
    timedRequest,
    timeout,
    invokeRequests,
    interactionModelRevision,
    suppressResponse,
    expectedProcessingTime,
    useExtendedFailSafeMessageResponseTimeout,
    // Additional meta-data for client side processing
    commands: commandMap,
    [import_general.Diagnostic.value]: () => import_general.Diagnostic.list(
      commands.map((cmd) => {
        const { commandRef } = cmd;
        const fields = "fields" in cmd ? cmd.fields : void 0;
        return [
          import_general.Diagnostic.strong((0, import_Specifier.resolvePathForSpecifier)(cmd)),
          "with",
          (0, import_general.isObject)(fields) ? import_general.Diagnostic.dict(fields) : "(no payload)",
          commandRef !== void 0 ? `(ref ${commandRef})` : ""
        ];
      })
    )
  };
}
((Invoke2) => {
  function Command(request, skipValidation = false) {
    const command = Invoke2.commandOf(request);
    const { requestSchema, requestId, timed } = command;
    const { commandRef } = request;
    let fields = "fields" in request ? request.fields : void 0;
    if (requestSchema instanceof import_types.ObjectSchema) {
      if (fields === void 0) {
        fields = {};
      }
      if (requestSchema.isFabricScoped && fields.fabricIndex === void 0) {
        fields.fabricIndex = import_types.FabricIndex.NO_FABRIC;
      }
    }
    if (!skipValidation) {
      requestSchema.validate(fields);
    }
    const commandFields = requestSchema.encodeTlv(fields);
    const result = {
      commandPath: {
        // Endpoint id is added below if not wildcard
        clusterId: import_Specifier.Specifier.clusterFor(request.cluster).id,
        commandId: requestId
      },
      commandFields,
      timed: timed ?? false,
      commandRef
    };
    const endpointId = import_Specifier.Specifier.endpointIdOf(request);
    if (endpointId !== void 0) {
      result.commandPath.endpointId = endpointId;
    }
    return result;
  }
  Invoke2.Command = Command;
  function ConcreteCommandRequest(data) {
    if (data.endpoint === void 0) {
      throw new import_MalformedRequestError.MalformedRequestError(`ConcreteCommandRequest requires an endpoint`);
    }
    return data;
  }
  Invoke2.ConcreteCommandRequest = ConcreteCommandRequest;
  function WildcardCommandRequest(data) {
    if ("endpoint" in data && data.endpoint !== void 0) {
      throw new import_MalformedRequestError.MalformedRequestError(`ConcreteCommandRequest must not have an endpoint`);
    }
    return data;
  }
  Invoke2.WildcardCommandRequest = WildcardCommandRequest;
  function commandOf(request) {
    if (typeof request.command === "string") {
      const cluster = import_Specifier.Specifier.clusterFor(request.cluster);
      const command = cluster.commands[request.command];
      if (command === void 0) {
        throw new import_MalformedRequestError.MalformedRequestError(`Cluster ${cluster.name} does not define command ${request.command}`);
      }
      return command;
    }
    return request.command;
  }
  Invoke2.commandOf = commandOf;
})(Invoke || (Invoke = {}));
//# sourceMappingURL=Invoke.js.map
