"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 DefaultValue_exports = {};
__export(DefaultValue_exports, {
  DefaultValue: () => DefaultValue
});
module.exports = __toCommonJS(DefaultValue_exports);
var import_general = require("@matter/general");
var import_common = require("../common/index.js");
var import_Model = require("../models/Model.js");
var import_FeatureMap = require("../standard/elements/FeatureMap.js");
/**
 * @license
 * Copyright 2022-2025 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
function DefaultValue(scope, model, ifValid = false) {
  const value = castValue(model, model.default);
  if (value === void 0) {
    return buildValue(scope, model, ifValid);
  }
  return value;
}
function castValue(model, modelDefault) {
  if (modelDefault === void 0) {
    return;
  }
  if (modelDefault === null) {
    if (model.nullable) {
      return null;
    }
    return;
  }
  const metatype = model.effectiveMetatype;
  switch (metatype) {
    case void 0:
    case import_common.Metatype.any:
      return import_common.FieldValue.unwrap(modelDefault);
    case import_common.Metatype.integer:
    case import_common.Metatype.float:
      return import_common.FieldValue.numericValue(modelDefault, model.type);
    case import_common.Metatype.enum:
      let enumValueModel;
      if (typeof modelDefault === "number" || typeof modelDefault === "string") {
        enumValueModel = model.member(modelDefault);
      }
      if (enumValueModel) {
        return enumValueModel.effectiveId;
      }
      return;
    case import_common.Metatype.bitmap:
      if (typeof modelDefault === "number" || typeof modelDefault === "bigint") {
        return decodeBitmap(model, modelDefault);
      }
      return import_common.FieldValue.objectValue(modelDefault);
    case import_common.Metatype.object:
      return import_common.FieldValue.objectValue(modelDefault);
    case import_common.Metatype.string:
      return `${modelDefault}`;
    case import_common.Metatype.bytes:
      if (ArrayBuffer.isView(modelDefault)) {
        return new Uint8Array(modelDefault.buffer, modelDefault.byteOffset, modelDefault.byteLength);
      }
      if (typeof modelDefault === "string") {
        return import_general.Bytes.fromHex(modelDefault);
      }
      return;
    case import_common.Metatype.date:
      if (modelDefault instanceof Date) {
        return modelDefault;
      }
      if (typeof modelDefault === "number" || typeof modelDefault === "string") return new Date(modelDefault);
      return;
    case import_common.Metatype.array:
      if (Array.isArray(modelDefault)) {
        const entry = model.member("entry");
        if (entry?.isType) {
          return modelDefault.map((value) => castValue(entry, value));
        }
        return modelDefault;
      }
      return;
    case import_common.Metatype.boolean:
      return !!modelDefault;
    default:
      throw new import_general.NotImplementedError(`Unsupported metatype "${metatype}"`);
  }
}
function buildValue(scope, model, ifValid) {
  switch (model.effectiveMetatype) {
    case import_common.Metatype.array:
      if (!model.nullable && model.effectiveMetatype === import_common.Metatype.array && !model.constraint.min && !model.constraint.value) {
        return [];
      }
      return;
    case import_common.Metatype.object:
      return buildObject(scope, model, ifValid);
    case import_common.Metatype.bitmap:
      return buildBitmap(scope, model);
  }
}
function buildObject(scope, model, ifValid) {
  let result;
  for (const child of scope.membersOf(model, { conformance: "conformant" })) {
    const name = (0, import_general.camelize)(child.name);
    if (result && result[name] !== void 0) {
      continue;
    }
    const value = DefaultValue(scope, child);
    if (value !== void 0) {
      if (!result) {
        result = {};
      }
      result[name] = value;
      continue;
    }
    if (ifValid && !child.nullable) {
      return;
    }
  }
  return result;
}
function buildBitmap(scope, model) {
  let result;
  let fieldsDefined = 0;
  for (const m of scope.membersOf(model, { conformance: "conformant" })) {
    const defaultValue = import_common.FieldValue.numericValue(m.default);
    if (defaultValue === void 0) {
      continue;
    }
    if (result === void 0) {
      result = 0;
    }
    let minBit, maxBit;
    const constraintValue = import_common.FieldValue.numericValue(m.constraint.value);
    if (constraintValue !== void 0) {
      minBit = constraintValue;
      maxBit = constraintValue + 1;
    } else {
      minBit = import_common.FieldValue.numericValue(m.constraint.min);
      maxBit = import_common.FieldValue.numericValue(m.constraint.max);
    }
    if (minBit === void 0) {
      minBit = 0;
    }
    if (maxBit === void 0) {
      maxBit = Math.trunc(Math.log2(defaultValue)) + 1;
    }
    for (let i = 0, mask = 1 << minBit; i < maxBit - minBit; i++, mask <<= 1) {
      if (fieldsDefined & mask) {
        continue;
      }
      fieldsDefined |= mask;
      if (defaultValue & 1 << i) {
        result |= mask;
      }
    }
  }
  return result;
}
function decodeBitmap(model, value) {
  const fields = /* @__PURE__ */ new Map();
  for (let bit = 0; Math.pow(bit, 2) <= value; bit++) {
    if (typeof value === "bigint") {
      if (!(value & 1n << BigInt(bit))) {
        continue;
      }
    } else if (!(value & 1 << bit)) {
      continue;
    }
    const definition = model.bitDefinition(bit);
    if (!definition) {
      continue;
    }
    const constraint = definition.effectiveConstraint;
    if (constraint.value !== void 0) {
      fields.set(definition, true);
    } else if (constraint.min !== void 0) {
      const fieldBit = 1 << bit - constraint.min;
      fields.set(definition, (fields.get(definition) ?? 0) & fieldBit);
    }
  }
  let nameGenerator;
  if (import_Model.Model.types[import_common.ElementTag.Attribute] && model.id === import_FeatureMap.FeatureMap.id) {
    nameGenerator = (model2) => model2.description === void 0 ? (0, import_general.camelize)(model2.name) : (0, import_general.camelize)(model2.description);
  } else {
    nameGenerator = (model2) => (0, import_general.camelize)(model2.name);
  }
  return Object.fromEntries([...fields.entries()].map(([k, v]) => [nameGenerator(k), v]));
}
//# sourceMappingURL=DefaultValue.js.map
