/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { Diagnostic, InternalError, Logger } from "#general";
import { IncomingInteractionClientMessenger } from "#interaction/InteractionMessenger.js";
import { Subscription } from "#interaction/Subscription.js";
import { SecureSession } from "#session/SecureSession.js";
import { INTERACTION_PROTOCOL_ID, Status } from "#types";
import { InputChunk } from "../InputChunk.js";
const logger = Logger.get("ClientSubscriptionHandler");
class ClientSubscriptionHandler {
  id = INTERACTION_PROTOCOL_ID;
  requiresSecureSession = true;
  #subscriptions;
  constructor(subscriptions) {
    this.#subscriptions = subscriptions;
  }
  async onNewExchange(exchange) {
    const messenger = new IncomingInteractionClientMessenger(exchange);
    const reports = messenger.readDataReports();
    const initialIteration = await reports.next();
    if (initialIteration.done) {
      throw new InternalError("Exchange initiated with no initial message");
    }
    const initialReport = initialIteration.value;
    const { subscriptionId } = initialReport;
    if (subscriptionId === void 0) {
      logger.debug(exchange.via, "Ignoring unsolicited data report with no subscription ID");
      await sendInvalid(messenger, void 0);
      return;
    }
    const { session } = exchange.channel;
    SecureSession.assert(session);
    const subscription = this.#subscriptions.getPeer(session.peerAddress, subscriptionId);
    if (subscription === void 0) {
      logger.info(
        exchange.via,
        "Ignoring data report for unknown subscription ID",
        Diagnostic.strong(Subscription.idStrOf(subscriptionId))
      );
      await sendInvalid(messenger, subscriptionId);
      return;
    }
    try {
      subscription.isReading = true;
      if (!initialReport.attributeReports?.length && !initialReport.eventReports?.length) {
        const ending = await reports.next();
        if (!ending.done) {
          logger.warn(
            exchange.via,
            "Unexpected data reports after empty report",
            Diagnostic.strong(Subscription.idStrOf(subscriptionId))
          );
          for await (const _chunk of reports) ;
        }
      } else {
        if (subscription.request.updated) {
          await subscription.request.updated(processReports(initialReport, reports, messenger));
        } else {
          for await (const _chunk of reports) ;
        }
      }
    } finally {
      subscription.isReading = false;
      subscription.timeoutAt = void 0;
      this.#subscriptions.resetTimer();
      await messenger.close();
    }
  }
  async close() {
  }
}
async function sendInvalid(messenger, subscriptionId) {
  await messenger.sendStatus(Status.InvalidSubscription, {
    multipleMessageInteraction: true,
    logContext: Subscription.diagnosticOf(subscriptionId)
  });
  await messenger.close();
}
async function* processReports(initialReport, otherReports, messenger) {
  const leftOverData = new Array();
  yield InputChunk(initialReport, leftOverData);
  const { subscriptionId } = initialReport;
  for await (const report of otherReports) {
    const { subscriptionId: reportSubscriptionId } = report;
    if (reportSubscriptionId === void 0) {
      logger.debug(messenger.exchange.via, "Ignoring data report with missing subscription id");
      await sendInvalid(messenger, reportSubscriptionId);
      continue;
    }
    if (reportSubscriptionId !== subscriptionId) {
      logger.debug(
        messenger.exchange.via,
        "Ignoring data report for incorrect subscription id",
        Diagnostic.strong(Subscription.idStrOf(reportSubscriptionId)),
        "expected",
        Subscription.idStrOf(subscriptionId)
      );
      await sendInvalid(messenger, reportSubscriptionId);
      continue;
    }
    yield InputChunk(report, leftOverData);
  }
}
export {
  ClientSubscriptionHandler
};
//# sourceMappingURL=ClientSubscriptionHandler.js.map
