/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { Bytes, Duration, isObject, UnexpectedDataError } from "@matter/general";
class UnsupportedCastError extends UnexpectedDataError {
}
var Metatype = /* @__PURE__ */ ((Metatype2) => {
  Metatype2["any"] = "any";
  Metatype2["boolean"] = "boolean";
  Metatype2["bitmap"] = "bitmap";
  Metatype2["enum"] = "enum";
  Metatype2["integer"] = "integer";
  Metatype2["float"] = "float";
  Metatype2["bytes"] = "bytes";
  Metatype2["array"] = "array";
  Metatype2["object"] = "object";
  Metatype2["string"] = "string";
  Metatype2["date"] = "date";
  Metatype2["duration"] = "duration";
  return Metatype2;
})(Metatype || {});
((Metatype2) => {
  function hasChildren(type) {
    switch (type) {
      case "enum" /* enum */:
      case "bitmap" /* bitmap */:
      case "object" /* object */:
        return true;
      default:
        return false;
    }
  }
  Metatype2.hasChildren = hasChildren;
  function native(type) {
    switch (type) {
      case "boolean" /* boolean */:
        return Boolean;
      case "integer" /* integer */:
        return BigInt;
      case "bitmap" /* bitmap */:
      case "enum" /* enum */:
      case "float" /* float */:
        return Number;
      case "bytes" /* bytes */:
        return Uint8Array;
      case "array" /* array */:
        return Array;
      case "object" /* object */:
        return Object;
      case "string" /* string */:
        return String;
      case "date" /* date */:
        return Date;
      case "duration" /* duration */:
        return Duration;
    }
  }
  Metatype2.native = native;
  function castFn(type, value) {
    const caster = Metatype2.cast[type];
    return caster(value);
  }
  Metatype2.cast = Object.assign(castFn, {
    any: (value) => value,
    boolean: (value) => {
      if (typeof value === "boolean" || value === null || value === void 0) {
        return value;
      }
      if (typeof value === "string") {
        const normalized = value.toLowerCase().trim();
        switch (normalized) {
          case "":
          case "0":
          case "off":
          case "no":
          case "false":
            return false;
          case "1":
          case "on":
          case "yes":
          case "true":
            return true;
        }
      }
      if (typeof value === "number" || typeof value === "bigint") {
        return !!value;
      }
      if (ArrayBuffer.isView(value)) {
        for (const byte of new Uint8Array(value.buffer)) {
          if (byte) {
            return true;
          }
        }
        return false;
      }
      throw new UnsupportedCastError(`Cannot convert "${value}" to boolean`);
    },
    bitmap: (value) => {
      if (value === null || value === void 0) {
        return value;
      }
      if (typeof value === "string") {
        value = Metatype2.cast.integer(value);
      }
      if (typeof value === "number") {
        if (Number.isFinite(value)) {
          return value;
        }
      } else if (typeof value === "bigint") {
        return value;
      } else if (isObject(value)) {
        return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, Metatype2.cast.integer(v)]));
      }
      throw new UnsupportedCastError(`Cannot convert "${value}" to bitmap`);
    },
    enum: (value) => {
      if (typeof value === "string") {
        if (value.trim().match(/^(?:\d+|0x[0-9a-f]+|0b[01]+)$/)) {
          value = Number.parseInt(value);
        } else {
          return value;
        }
      }
      if (typeof value === "number" && Number.isFinite(value)) {
        return value;
      }
      throw new UnsupportedCastError(`Cannot convert "${value}" to an enum value`);
    },
    integer: (value) => {
      if (value === null || value === void 0) {
        return value;
      }
      switch (typeof value) {
        case "number":
          return Math.floor(value);
        case "bigint":
          return value;
        case "boolean":
          return value ? 1 : 0;
      }
      if (value instanceof Date) {
        return value.getTime();
      }
      if (typeof value === "string") {
        try {
          const big = BigInt(value);
          const little = Number.parseInt(value);
          if (big === BigInt(little)) {
            return little;
          }
          return big;
        } catch (e) {
          if (!(e instanceof SyntaxError)) {
            throw e;
          }
        }
      }
      throw new UnsupportedCastError(`Cannot convert "${value}" to an integer`);
    },
    float: (value) => {
      if (typeof value === "number" || value === null || value === void 0) {
        return value;
      }
      if (value instanceof Date) {
        return value.getTime();
      }
      const number = Number(value);
      if (Number.isFinite(value)) {
        return number;
      }
      throw new UnsupportedCastError(`Cannot convert "${value}" to a float`);
    },
    bytes: (value) => {
      if (value === void 0 || value === null || Bytes.isBytes(value)) {
        return value;
      }
      if (typeof value === "string") {
        return Bytes.fromHex(value);
      }
      if (typeof value === "boolean") {
        return new Uint8Array([value ? 1 : 0]);
      }
      if (typeof value === "number" || typeof value === "bigint") {
        return Bytes.fromHex(value.toString(16));
      }
      throw new UnsupportedCastError(`Cannot convert "${value}" to bytes`);
    },
    array: (value) => {
      if (value === void 0 || value === null || Array.isArray(value)) {
        return value;
      }
      if (typeof value === "string") {
        try {
          const parsed = JSON.parse(value);
          if (Array.isArray(parsed)) {
            return parsed;
          }
        } catch (e) {
          if (!(e instanceof SyntaxError)) {
            throw e;
          }
        }
      }
      throw new UnsupportedCastError(`Cannot convert "${value}" to array`);
    },
    object: (value) => {
      if (value === void 0 || typeof value === "object" && !Array.isArray(value) && !(value instanceof Date)) {
        return value;
      }
      if (typeof value === "string") {
        try {
          const parsed = JSON.parse(value);
          return parsed;
        } catch (e) {
          if (!(e instanceof SyntaxError)) {
            throw e;
          }
        }
      }
      throw new UnsupportedCastError(`Cannot convert "${value}" to object`);
    },
    string: (value) => {
      if (value === void 0 || value === null) {
        return value;
      }
      if (typeof value === "string") {
        return value;
      }
      if (value instanceof Date) {
        return value.toISOString();
      }
      if (typeof value === "object" || Array.isArray(value)) {
        return JSON.stringify(value);
      }
      return value.toString();
    },
    date: (value) => {
      if (value === void 0 || value === null || value instanceof Date) {
        return value;
      }
      if (typeof value === "number" || typeof value === "string") {
        const date = new Date(value);
        if (Number.isFinite(date.getTime())) {
          return date;
        }
      }
      throw new UnexpectedDataError("Invalid date value");
    },
    duration: (value) => {
      if (value === void 0 || value === null) {
        return value;
      }
      return Duration(value);
    }
  });
})(Metatype || (Metatype = {}));
export {
  Metatype,
  UnsupportedCastError
};
//# sourceMappingURL=Metatype.js.map
