/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { Bytes, ImplementationError, serialize, UnexpectedDataError } from "@matter/general";
import { ValidationDatatypeMismatchError, ValidationOutOfBoundsError } from "../common/ValidationError.js";
import { TlvCodec, TlvType } from "./TlvCodec.js";
import { TlvSchema } from "./TlvSchema.js";
const stringBoundCache = /* @__PURE__ */ new WeakMap();
class StringSchema extends TlvSchema {
  constructor(type, minLength = 0, maxLength = 1024) {
    super();
    this.type = type;
    this.minLength = minLength;
    this.maxLength = maxLength;
    if (minLength < 0) throw new ImplementationError("Minimum length should be a positive number.");
    if (maxLength < 0) throw new ImplementationError("Maximum length should be a positive number.");
    if (minLength > maxLength)
      throw new ImplementationError("Minimum length should be smaller than maximum length.");
  }
  encodeTlvInternal(writer, value, tag) {
    const length = typeof value === "string" ? value.length : value.byteLength;
    const typeLength = { type: this.type, length: TlvCodec.getUIntTlvLength(length) };
    writer.writeTag(typeLength, tag);
    writer.writePrimitive(typeLength, value);
  }
  decodeTlvInternalValue(reader, typeLength) {
    if (typeLength.type !== this.type) throw new UnexpectedDataError(`Unexpected type ${typeLength.type}.`);
    return reader.readPrimitive(typeLength);
  }
  validate(value) {
    if (this.type === TlvType.Utf8String && typeof value !== "string")
      throw new ValidationDatatypeMismatchError(`Expected string, got ${typeof value}.`);
    if (this.type === TlvType.ByteString && !Bytes.isBytes(value))
      throw new ValidationDatatypeMismatchError(`Expected bytes, got ${typeof value}.`);
    const length = typeof value === "string" ? value.length : value.byteLength;
    if (length > this.maxLength)
      throw new ValidationOutOfBoundsError(
        `String ${serialize(value)} is too long: ${length}, max ${this.maxLength}.`
      );
    if (length < this.minLength)
      throw new ValidationOutOfBoundsError(
        `String ${serialize(value)} is too short: ${length}, min ${this.minLength}.`
      );
  }
  /** @deprecated Part of old ClusterType() compat layer. */
  get element() {
    const result = {
      type: this.type === TlvType.Utf8String ? "string" : "octstr"
    };
    const constraint = {};
    if (this.minLength > 0) {
      constraint.min = this.minLength;
    }
    if (this.maxLength !== 1024) {
      constraint.max = this.maxLength;
    }
    if (constraint.min !== void 0 || constraint.max !== void 0) {
      result.constraint = constraint;
    }
    return result;
  }
  bound({ minLength, maxLength, length }) {
    const effectiveMin = length ?? minLength ?? this.minLength;
    const effectiveMax = length ?? maxLength ?? this.maxLength;
    const key = `${effectiveMin}:${effectiveMax}`;
    let inner = stringBoundCache.get(this);
    if (inner === void 0) {
      inner = /* @__PURE__ */ new Map();
      stringBoundCache.set(this, inner);
    }
    let result = inner.get(key);
    if (result === void 0) {
      result = new StringSchema(this.type, effectiveMin, effectiveMax);
      inner.set(key, result);
    }
    return result;
  }
}
const TlvByteString = new StringSchema(TlvType.ByteString);
const TlvString = new StringSchema(TlvType.Utf8String);
const TlvString32max = TlvString.bound({ maxLength: 32 });
const TlvString64max = TlvString.bound({ maxLength: 64 });
const TlvString256max = TlvString.bound({ maxLength: 256 });
const TlvHardwareAddress = TlvByteString.bound({ minLength: 6, maxLength: 8 });
export {
  StringSchema,
  TlvByteString,
  TlvHardwareAddress,
  TlvString,
  TlvString256max,
  TlvString32max,
  TlvString64max
};
//# sourceMappingURL=TlvString.js.map
