/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { ChannelType, MatterFlowError, Millis, Seconds } from "@matter/general";
var MRP;
((MRP2) => {
  MRP2.MAX_TRANSMISSIONS = 5;
  MRP2.BACKOFF_BASE = 1.6;
  MRP2.BACKOFF_JITTER = 0.25;
  MRP2.BACKOFF_MARGIN = 1.1;
  MRP2.BACKOFF_THRESHOLD = 1;
  MRP2.STANDALONE_ACK_TIMEOUT = Millis(200);
  MRP2.DEFAULT_EXPECTED_PROCESSING_TIME = Seconds(2);
  MRP2.ADDITIONAL_MRP_DELAY = Seconds(1.5);
  const PEER_RESPONSE_TIME_BUFFER = Seconds(5);
  function maxPeerResponseTimeOf({
    peerSessionParameters,
    localSessionParameters,
    channelType,
    isPeerActive,
    usesMrp = channelType === ChannelType.UDP,
    expectedProcessingTime = MRP2.DEFAULT_EXPECTED_PROCESSING_TIME
  }) {
    switch (channelType) {
      case "tcp":
        return Millis(Seconds(30) + PEER_RESPONSE_TIME_BUFFER);
      case "udp":
        if (!usesMrp) {
          throw new MatterFlowError("No response expected for this message exchange because UDP and no MRP");
        }
        return Millis(
          (peerSessionParameters !== void 0 ? maxResponseTimeOf(peerSessionParameters, isPeerActive) : 0) + maxResponseTimeOf(localSessionParameters, true) + // We consider us as always active initially
          expectedProcessingTime + PEER_RESPONSE_TIME_BUFFER
        );
      case "ble":
        return Millis(Seconds(30) + PEER_RESPONSE_TIME_BUFFER);
      default:
        throw new MatterFlowError(
          `Can not calculate expected timeout for unknown channel type: ${channelType}`
        );
    }
  }
  MRP2.maxPeerResponseTimeOf = maxPeerResponseTimeOf;
  function maxRetransmissionIntervalOf(inputs) {
    return retransmissionIntervalOf(inputs, true);
  }
  MRP2.maxRetransmissionIntervalOf = maxRetransmissionIntervalOf;
  function retransmissionIntervalOf({ transmissionNumber, sessionParameters, isPeerActive }, calculateMaximum = false) {
    const { activeInterval, idleInterval } = sessionParameters;
    const peerActive = transmissionNumber > 0 && (!calculateMaximum || isPeerActive);
    let baseInterval = peerActive ? activeInterval : idleInterval;
    if (!calculateMaximum) {
      baseInterval += MRP2.ADDITIONAL_MRP_DELAY;
    }
    return Millis.floor(
      Millis(
        baseInterval * MRP2.BACKOFF_MARGIN * Math.pow(MRP2.BACKOFF_BASE, Math.max(0, transmissionNumber - MRP2.BACKOFF_THRESHOLD)) * (1 + (calculateMaximum ? 1 : Math.random()) * MRP2.BACKOFF_JITTER)
      )
    );
  }
  MRP2.retransmissionIntervalOf = retransmissionIntervalOf;
})(MRP || (MRP = {}));
function maxResponseTimeOf(sessionParameters, isPeerActive) {
  let finalWaitTime = 0;
  for (let i = 0; i < MRP.MAX_TRANSMISSIONS; i++) {
    if (isPeerActive && finalWaitTime > sessionParameters.activeThreshold) {
      isPeerActive = false;
    }
    finalWaitTime = Millis(
      finalWaitTime + MRP.maxRetransmissionIntervalOf({
        transmissionNumber: i,
        sessionParameters,
        isPeerActive
      })
    );
  }
  return finalWaitTime;
}
export {
  MRP
};
//# sourceMappingURL=MRP.js.map
