"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 TlvArray_exports = {};
__export(TlvArray_exports, {
  ArraySchema: () => ArraySchema,
  TlvArray: () => TlvArray
});
module.exports = __toCommonJS(TlvArray_exports);
var import_general = require("@matter/general");
var import_model = require("@matter/model");
var import_ValidationError = require("../common/ValidationError.js");
var import_TlvCodec = require("./TlvCodec.js");
var import_TlvSchema = require("./TlvSchema.js");
/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
class ArraySchema extends import_TlvSchema.TlvSchema {
  constructor(elementSchema, minLength = 0, maxLength = 65535) {
    super();
    this.elementSchema = elementSchema;
    this.minLength = minLength;
    this.maxLength = maxLength;
  }
  /** @deprecated Part of old ClusterType() compat layer. */
  get element() {
    const result = { type: "list" };
    const entryElement = this.elementSchema.element;
    if (entryElement) {
      result.children = [(0, import_model.FieldElement)({ name: "entry", ...entryElement })];
    }
    const constraint = {};
    if (this.minLength > 0) {
      constraint.min = this.minLength;
    }
    if (this.maxLength < 65535) {
      constraint.max = this.maxLength;
    }
    if (constraint.min !== void 0 || constraint.max !== void 0) {
      result.constraint = constraint;
    }
    return result;
  }
  encodeTlvInternal(writer, value, tag, options) {
    writer.writeTag({ type: import_TlvCodec.TlvType.Array }, tag);
    value.forEach((element) => this.elementSchema.encodeTlvInternal(writer, element, void 0, options));
    writer.writeTag({ type: import_TlvCodec.TlvType.EndOfContainer });
  }
  decodeTlvInternalValue(reader, typeLength) {
    if (typeLength.type !== import_TlvCodec.TlvType.Array)
      throw new import_general.UnexpectedDataError(`Unexpected type ${typeLength.type}, expected Array (${import_TlvCodec.TlvType.Array}).`);
    const result = new Array();
    while (true) {
      const { tag: elementTag, typeLength: elementTypeLength } = reader.readTagType();
      if (elementTag !== void 0) throw new import_general.UnexpectedDataError("Array element tags should be anonymous.");
      if (elementTypeLength.type === import_TlvCodec.TlvType.EndOfContainer) break;
      result.push(this.elementSchema.decodeTlvInternalValue(reader, elementTypeLength));
    }
    return result;
  }
  injectField(value, fieldId, fieldValue, injectChecker) {
    if (Array.isArray(value)) {
      value.forEach(
        (item, index) => value[index] = this.elementSchema.injectField(item, fieldId, fieldValue, injectChecker)
      );
    }
    return value;
  }
  removeField(value, fieldId, removeChecker) {
    if (Array.isArray(value)) {
      value.forEach(
        (item, index) => value[index] = this.elementSchema.removeField(item, fieldId, removeChecker)
      );
    }
    return value;
  }
  validate(data) {
    if (!Array.isArray(data)) throw new import_ValidationError.ValidationDatatypeMismatchError(`Expected array, got ${typeof data}.`);
    if (data.length > this.maxLength)
      throw new import_ValidationError.ValidationOutOfBoundsError(
        `Array ${(0, import_general.serialize)(data)} is too long: ${data.length}, max ${this.maxLength}.`
      );
    if (data.length < this.minLength)
      throw new import_ValidationError.ValidationOutOfBoundsError(
        `Array ${(0, import_general.serialize)(data)} is too short: ${data.length}, min ${this.minLength}.`
      );
    data.forEach((element, index) => {
      try {
        this.elementSchema.validate(element);
      } catch (e) {
        import_ValidationError.ValidationError.accept(e);
        e.fieldName = `[${index}]${e.fieldName !== void 0 ? `.${e.fieldName}` : ""}`;
        throw e;
      }
    });
  }
  decodeFromChunkedArray(chunks, currentValue) {
    if (currentValue === void 0 && chunks[0].listIndex !== void 0) {
      throw new import_general.UnexpectedDataError(
        `When no current value is supplied the first chunked element needs to have a list index of undefined, but received ${chunks[0].listIndex}.`
      );
    }
    currentValue = currentValue !== void 0 ? (0, import_general.deepCopy)(currentValue) : [];
    for (const { listIndex, element } of chunks) {
      if (listIndex === void 0) {
        currentValue = this.decodeTlv(element);
      } else if (listIndex === null) {
        const decodedElement = this.elementSchema.decodeTlv(element);
        currentValue.push(decodedElement);
      } else if (element[0].typeLength.type === import_TlvCodec.TlvType.Null) {
        currentValue.splice(listIndex, 1);
      } else {
        currentValue[listIndex] = this.elementSchema.decodeTlv(element);
      }
    }
    return currentValue;
  }
  encodeAsChunkedArray(value, options) {
    const result = [];
    result.push({ listIndex: void 0, element: this.encodeTlv([], options) });
    value.forEach((element) => {
      const elementStream = this.elementSchema.encodeTlv(element, options);
      result.push({ listIndex: null, element: elementStream });
    });
    return result;
  }
}
const arrayCache = /* @__PURE__ */ new WeakMap();
const TlvArray = (elementSchema, { minLength, maxLength, length } = {}) => {
  const effectiveMin = length ?? minLength;
  const effectiveMax = length ?? maxLength;
  const key = `${effectiveMin}:${effectiveMax}`;
  let inner = arrayCache.get(elementSchema);
  if (inner === void 0) {
    inner = /* @__PURE__ */ new Map();
    arrayCache.set(elementSchema, inner);
  }
  let result = inner.get(key);
  if (result === void 0) {
    result = new ArraySchema(elementSchema, effectiveMin, effectiveMax);
    inner.set(key, result);
  }
  return result;
};
//# sourceMappingURL=TlvArray.js.map
