"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
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 Primitive_exports = {};
__export(Primitive_exports, {
  IntegerLimits: () => IntegerLimits,
  NOT_KNOWN: () => NOT_KNOWN,
  UNKNOWN_STATE: () => UNKNOWN_STATE,
  encodeBitMask: () => encodeBitMask,
  encodeBoolean: () => encodeBoolean,
  encodeFloatWithScale: () => encodeFloatWithScale,
  encodeLongRangeNodeBitMask: () => encodeLongRangeNodeBitMask,
  encodeMaybeBoolean: () => encodeMaybeBoolean,
  encodeNodeBitMask: () => encodeNodeBitMask,
  encodePartial: () => encodePartial,
  getFloatParameters: () => getFloatParameters,
  getIntegerLimits: () => getIntegerLimits,
  getMinIntegerSize: () => getMinIntegerSize,
  maybeUnknownToString: () => maybeUnknownToString,
  parseBitMask: () => parseBitMask,
  parseBoolean: () => parseBoolean,
  parseFloatWithScale: () => parseFloatWithScale,
  parseLongRangeNodeBitMask: () => parseLongRangeNodeBitMask,
  parseMaybeBoolean: () => parseMaybeBoolean,
  parseMaybeNumber: () => parseMaybeNumber,
  parseNodeBitMask: () => parseNodeBitMask,
  parseNumber: () => parseNumber,
  parsePartial: () => parsePartial
});
module.exports = __toCommonJS(Primitive_exports);
var import_shared = require("@zwave-js/shared");
var import_consts = require("../definitions/consts.js");
var import_ZWaveError = require("../error/ZWaveError.js");
var import_misc = require("../util/misc.js");
const NOT_KNOWN = void 0;
const UNKNOWN_STATE = null;
function parseMaybeBoolean(val) {
  return val === 254 ? UNKNOWN_STATE : parseBoolean(val);
}
__name(parseMaybeBoolean, "parseMaybeBoolean");
function parseBoolean(val) {
  return val === 0 ? false : val === 255 ? true : void 0;
}
__name(parseBoolean, "parseBoolean");
function encodeBoolean(val) {
  return val ? 255 : 0;
}
__name(encodeBoolean, "encodeBoolean");
function encodeMaybeBoolean(val) {
  return val === UNKNOWN_STATE ? 254 : val ? 255 : 0;
}
__name(encodeMaybeBoolean, "encodeMaybeBoolean");
function parseMaybeNumber(val) {
  return val === 254 ? UNKNOWN_STATE : parseNumber(val);
}
__name(parseMaybeNumber, "parseMaybeNumber");
function parseNumber(val) {
  return val <= 99 ? val : val === 255 ? 99 : void 0;
}
__name(parseNumber, "parseNumber");
function maybeUnknownToString(val, ifNotUnknown = (val2) => val2.toString()) {
  return val === void 0 ? "undefined" : val === UNKNOWN_STATE ? "unknown" : ifNotUnknown(val);
}
__name(maybeUnknownToString, "maybeUnknownToString");
function parseFloatWithScale(payload, allowEmpty = false) {
  (0, import_misc.validatePayload)(payload.length >= 1);
  const buffer = import_shared.Bytes.view(payload);
  const precision = (buffer[0] & 224) >>> 5;
  const scale = (buffer[0] & 24) >>> 3;
  const size = buffer[0] & 7;
  if (allowEmpty && size === 0) {
    (0, import_misc.validatePayload)(precision === 0, scale === 0);
    return { bytesRead: 1 };
  } else {
    (0, import_misc.validatePayload)(size >= 1, size <= 4, buffer.length >= 1 + size);
    const value = buffer.readIntBE(1, size) / Math.pow(10, precision);
    return { value, scale, bytesRead: 1 + size };
  }
}
__name(parseFloatWithScale, "parseFloatWithScale");
function getPrecision(num) {
  if (!Number.isFinite(num))
    return 0;
  let e = 1;
  let p = 0;
  while (Math.round(num * e) / e !== num) {
    e *= 10;
    p++;
  }
  return p;
}
__name(getPrecision, "getPrecision");
const IntegerLimits = Object.freeze({
  UInt8: Object.freeze({ min: 0, max: 255 }),
  UInt16: Object.freeze({ min: 0, max: 65535 }),
  UInt24: Object.freeze({ min: 0, max: 16777215 }),
  UInt32: Object.freeze({ min: 0, max: 4294967295 }),
  Int8: Object.freeze({ min: -128, max: 127 }),
  Int16: Object.freeze({ min: -32768, max: 32767 }),
  Int24: Object.freeze({ min: -8388608, max: 8388607 }),
  Int32: Object.freeze({ min: -2147483648, max: 2147483647 })
});
function getMinIntegerSize(value, signed) {
  if (signed) {
    if (value >= IntegerLimits.Int8.min && value <= IntegerLimits.Int8.max) {
      return 1;
    } else if (value >= IntegerLimits.Int16.min && value <= IntegerLimits.Int16.max) {
      return 2;
    } else if (value >= IntegerLimits.Int32.min && value <= IntegerLimits.Int32.max) {
      return 4;
    }
  } else if (value >= 0) {
    if (value <= IntegerLimits.UInt8.max)
      return 1;
    if (value <= IntegerLimits.UInt16.max)
      return 2;
    if (value <= IntegerLimits.UInt32.max)
      return 4;
  }
}
__name(getMinIntegerSize, "getMinIntegerSize");
function getIntegerLimits(size, signed) {
  return IntegerLimits[`${signed ? "" : "U"}Int${size * 8}`];
}
__name(getIntegerLimits, "getIntegerLimits");
function getFloatParameters(value) {
  const precision = Math.min(getPrecision(value), 7);
  value = Math.round(value * Math.pow(10, precision));
  const size = getMinIntegerSize(value, true);
  if (size == void 0) {
    throw new import_ZWaveError.ZWaveError(`Cannot encode the value ${value} because its too large or too small to fit into 4 bytes`, import_ZWaveError.ZWaveErrorCodes.Arithmetic);
  }
  return {
    precision,
    size,
    roundedValue: value
  };
}
__name(getFloatParameters, "getFloatParameters");
function encodeFloatWithScale(value, scale, override = {}) {
  const precision = override.precision ?? Math.min(getPrecision(value), 7);
  value = Math.round(value * Math.pow(10, precision));
  let size = getMinIntegerSize(value, true);
  if (size == void 0) {
    throw new import_ZWaveError.ZWaveError(`Cannot encode the value ${value} because its too large or too small to fit into 4 bytes`, import_ZWaveError.ZWaveErrorCodes.Arithmetic);
  } else if (override.size != void 0 && override.size > size) {
    size = override.size;
  }
  const ret = new import_shared.Bytes(1 + size);
  ret[0] = (precision & 7) << 5 | (scale & 3) << 3 | size & 7;
  ret.writeIntBE(value, 1, size);
  return ret;
}
__name(encodeFloatWithScale, "encodeFloatWithScale");
function parseBitMask(mask, startValue = 1, numBits = mask.length * 8) {
  const ret = [];
  for (let index = 0; index < numBits; index++) {
    const byteNum = index >>> 3;
    const bitNum = index % 8;
    if ((mask[byteNum] & 2 ** bitNum) !== 0) {
      ret.push(index + startValue);
    }
  }
  return ret;
}
__name(parseBitMask, "parseBitMask");
function encodeBitMask(values, maxValue = Math.max(...values), startValue = 1) {
  if (!Number.isFinite(maxValue))
    return import_shared.Bytes.from([0]);
  const numBytes = Math.ceil((maxValue - startValue + 1) / 8);
  const ret = new import_shared.Bytes(numBytes).fill(0);
  for (let val = startValue; val <= maxValue; val++) {
    if (!values.includes(val))
      continue;
    const byteNum = val - startValue >>> 3;
    const bitNum = (val - startValue) % 8;
    ret[byteNum] |= 2 ** bitNum;
  }
  return ret;
}
__name(encodeBitMask, "encodeBitMask");
function parseNodeBitMask(mask) {
  return parseBitMask(mask.subarray(0, import_consts.NUM_NODEMASK_BYTES));
}
__name(parseNodeBitMask, "parseNodeBitMask");
function parseLongRangeNodeBitMask(mask, startValue) {
  return parseBitMask(mask, startValue);
}
__name(parseLongRangeNodeBitMask, "parseLongRangeNodeBitMask");
function encodeNodeBitMask(nodeIDs) {
  return encodeBitMask(nodeIDs, import_consts.MAX_NODES_LR);
}
__name(encodeNodeBitMask, "encodeNodeBitMask");
function encodeLongRangeNodeBitMask(nodeIDs, startValue) {
  return encodeBitMask(nodeIDs, startValue + import_consts.NUM_LR_NODES_PER_SEGMENT - 1, startValue);
}
__name(encodeLongRangeNodeBitMask, "encodeLongRangeNodeBitMask");
function parsePartial(value, bitMask, signed) {
  const shift = (0, import_misc.getMinimumShiftForBitMask)(bitMask);
  const width = (0, import_misc.getBitMaskWidth)(bitMask);
  let ret = (value & bitMask) >>> shift;
  if (signed && !!(ret & 2 ** (width - 1))) {
    ret = ~(~ret & bitMask >>> shift);
  }
  return ret;
}
__name(parsePartial, "parsePartial");
function encodePartial(fullValue, partialValue, bitMask) {
  const ret = fullValue & ~bitMask | partialValue << (0, import_misc.getMinimumShiftForBitMask)(bitMask) & bitMask;
  return ret >>> 0;
}
__name(encodePartial, "encodePartial");
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  IntegerLimits,
  NOT_KNOWN,
  UNKNOWN_STATE,
  encodeBitMask,
  encodeBoolean,
  encodeFloatWithScale,
  encodeLongRangeNodeBitMask,
  encodeMaybeBoolean,
  encodeNodeBitMask,
  encodePartial,
  getFloatParameters,
  getIntegerLimits,
  getMinIntegerSize,
  maybeUnknownToString,
  parseBitMask,
  parseBoolean,
  parseFloatWithScale,
  parseLongRangeNodeBitMask,
  parseMaybeBoolean,
  parseMaybeNumber,
  parseNodeBitMask,
  parseNumber,
  parsePartial
});
//# sourceMappingURL=Primitive.js.map
