/**
 * @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 cast(type, value) {
    const caster = cast[type];
    return caster(value);
  }
  Metatype2.cast = cast;
  cast.any = (value) => value;
  cast.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`);
  };
  cast.bitmap = (value) => {
    if (value === null || value === void 0) {
      return value;
    }
    if (typeof value === "string") {
      value = 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, cast.integer(v)]));
    }
    throw new UnsupportedCastError(`Cannot convert "${value}" to bitmap`);
  };
  cast.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`);
  };
  cast.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`);
  };
  cast.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`);
  };
  cast.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`);
  };
  cast.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`);
  };
  cast.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`);
  };
  cast.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();
  };
  cast.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");
  };
  cast.duration = (value) => {
    if (value === void 0 || value === null) {
      return value;
    }
    return Duration(value);
  };
})(Metatype || (Metatype = {}));
export {
  Metatype,
  UnsupportedCastError
};
//# sourceMappingURL=Metatype.js.map
