/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { Bytes, ImplementationError, InternalError } from "#general";
import { PersistedMessageCounter } from "#protocol/MessageCounter.js";
import { MessageReceptionStateEncryptedWithRollover } from "#protocol/MessageReceptionState.js";
class MessagingState {
  /**
   * Message counter for sending data messages to a group per Operational key. No need to scope to a source node
   * because we are the sending node
   * TODO: For management: Make sure to start rotating the key early enough that a former counter-value is not used
   *  again for the same key.
   */
  #groupDataCounters = /* @__PURE__ */ new Map();
  /** Message reception state for data messages per Operational key and source node. */
  #messageDataReceptionState = /* @__PURE__ */ new Map();
  #crypto;
  #storage;
  constructor(crypto, storage) {
    this.#crypto = crypto;
    if (storage !== void 0) {
      this.#storage = storage;
    }
  }
  set storage(storage) {
    if (this.#storage !== void 0) {
      throw new InternalError("Storage context can only be set once.");
    }
    this.#storage = storage;
  }
  /**
   * Return the message counter for sending messages to a group with the given operational key.
   */
  counterFor(operationalKey) {
    if (!this.#storage) {
      throw new ImplementationError("Group session cannot be created without storage context.");
    }
    const operationalKeyHex = Bytes.toHex(operationalKey);
    let counter = this.#groupDataCounters.get(operationalKeyHex);
    if (counter === void 0) {
      counter = new PersistedMessageCounter(this.#crypto, this.#storage, `${operationalKeyHex}-data`);
      this.#groupDataCounters.set(operationalKeyHex, counter);
    }
    return counter;
  }
  async removeCounter(key, forDelete = false) {
    const operationalKeyHex = Bytes.toHex(key);
    this.#groupDataCounters.delete(operationalKeyHex);
    if (forDelete) {
      await this.#storage?.delete(`${operationalKeyHex}-data`);
    }
  }
  /**
   * Returns the message reception state for a given source node id and operational key.
   */
  receptionStateFor(sourceNodeId, operationalKey) {
    const operationalKeyHex = Bytes.toHex(operationalKey);
    let receptionState = this.#messageDataReceptionState.get(operationalKeyHex)?.get(sourceNodeId);
    if (receptionState === void 0) {
      receptionState = new MessageReceptionStateEncryptedWithRollover();
      const keyMap = this.#messageDataReceptionState.get(operationalKeyHex) ?? /* @__PURE__ */ new Map();
      keyMap.set(sourceNodeId, receptionState);
      this.#messageDataReceptionState.set(operationalKeyHex, keyMap);
    }
    return receptionState;
  }
}
export {
  MessagingState
};
//# sourceMappingURL=MessagingState.js.map
