"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 SecureChannelProtocol_exports = {};
__export(SecureChannelProtocol_exports, {
  SecureChannelProtocol: () => SecureChannelProtocol,
  StatusReportOnlySecureChannelProtocol: () => StatusReportOnlySecureChannelProtocol
});
module.exports = __toCommonJS(SecureChannelProtocol_exports);
var import_FabricManager = require("#fabric/FabricManager.js");
var import_ExchangeManager = require("#protocol/ExchangeManager.js");
var import_NodeSession = require("#session/NodeSession.js");
var import_SessionManager = require("#session/SessionManager.js");
var import_general = require("@matter/general");
var import_types = require("@matter/types");
var import_CaseServer = require("../session/case/CaseServer.js");
var import_PaseServer = require("../session/pase/PaseServer.js");
var import_SecureChannelMessenger = require("./SecureChannelMessenger.js");
var import_SecureChannelStatusMessageSchema = require("./SecureChannelStatusMessageSchema.js");
/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
const logger = import_general.Logger.get("SecureChannelProtocol");
class StatusReportOnlySecureChannelProtocol {
  id = import_types.SECURE_CHANNEL_PROTOCOL_ID;
  // We need to check the message details to decide if ok or not, so we take them all
  requiresSecureSession = void 0;
  async onNewExchange(exchange, message) {
    const messageType = message.payloadHeader.messageType;
    switch (messageType) {
      case import_types.SecureMessageType.StatusReport:
        await this.handleInitialStatusReport(exchange, message);
        break;
      default:
        if (messageType !== import_types.SecureMessageType.StandaloneAck) {
          throw new import_types.StatusResponseError(
            `Unexpected initial message on secure channel protocol: ${messageType.toString(16)}`,
            import_types.StatusCode.InvalidAction
          );
        }
    }
  }
  async handleInitialStatusReport(exchange, message) {
    const {
      payloadHeader: { messageType },
      payload
    } = message;
    if (messageType !== import_types.SecureMessageType.StatusReport) {
      throw new import_general.MatterFlowError(
        `Unexpected message type on secure channel protocol, expected StatusReport: ${messageType.toString(
          16
        )}`
      );
    }
    const { generalStatus, protocolId, protocolStatus } = import_SecureChannelStatusMessageSchema.SecureChannelStatusMessage.decode(payload);
    if (generalStatus !== import_types.GeneralStatusCode.Success) {
      throw new import_SecureChannelMessenger.ChannelStatusResponseError(
        `Received general error status (${protocolId})`,
        generalStatus,
        protocolStatus
      );
    }
    if (protocolStatus !== import_types.SecureChannelStatusCode.CloseSession) {
      throw new import_SecureChannelMessenger.ChannelStatusResponseError(
        `Received general success status, but protocol status is not CloseSession`,
        generalStatus,
        protocolStatus
      );
    }
    const { session } = exchange;
    import_NodeSession.NodeSession.assert(session);
    logger.debug(exchange.via, "Closed by peer");
    await session.handlePeerClose(exchange);
  }
  async close() {
  }
}
class SecureChannelProtocol extends StatusReportOnlySecureChannelProtocol {
  #paseCommissioner;
  #caseCommissioner;
  #tooManyPaseErrors = (0, import_general.AsyncObservable)();
  constructor(sessions, fabrics) {
    super();
    this.#caseCommissioner = new import_CaseServer.CaseServer(sessions, fabrics);
  }
  static [import_general.Environmental.create](env) {
    const instance = new SecureChannelProtocol(env.get(import_SessionManager.SessionManager), env.get(import_FabricManager.FabricManager));
    env.get(import_ExchangeManager.ExchangeManager).addProtocolHandler(instance);
    env.set(SecureChannelProtocol, instance);
    return instance;
  }
  /**
   * Emitted when the active PASE session hits the maximum error threshold.
   */
  get tooManyPaseErrors() {
    return this.#tooManyPaseErrors;
  }
  setPaseCommissioner(paseServer) {
    this.#paseCommissioner = paseServer;
  }
  async removePaseCommissioner() {
    await this.#paseCommissioner?.close();
    this.#paseCommissioner = void 0;
  }
  async onNewExchange(exchange, message) {
    const messageType = message.payloadHeader.messageType;
    switch (messageType) {
      case import_types.SecureMessageType.PbkdfParamRequest:
        if (this.#paseCommissioner === void 0) {
          const messenger = new import_SecureChannelMessenger.SecureChannelMessenger(exchange);
          await messenger.sendError(import_types.SecureChannelStatusCode.InvalidParam);
          await messenger.close();
          return;
        }
        try {
          await this.#paseCommissioner.onNewExchange(exchange);
        } catch (error) {
          import_PaseServer.MaximumPasePairingErrorsReachedError.accept(error);
          await this.#tooManyPaseErrors.emit();
        }
        break;
      case import_types.SecureMessageType.Sigma1:
        await this.#caseCommissioner.onNewExchange(exchange);
        break;
      default:
        await super.onNewExchange(exchange, message);
    }
  }
}
//# sourceMappingURL=SecureChannelProtocol.js.map
