"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 Bootloader_exports = {};
__export(Bootloader_exports, {
  Bootloader: () => Bootloader,
  BootloaderState: () => BootloaderState
});
module.exports = __toCommonJS(Bootloader_exports);
var import_core = require("@zwave-js/core");
var import_serial = require("@zwave-js/serial");
var import_shared = require("@zwave-js/shared");
var BootloaderState;
(function(BootloaderState2) {
  BootloaderState2[BootloaderState2["Menu"] = 0] = "Menu";
  BootloaderState2[BootloaderState2["UploadingFirmware"] = 1] = "UploadingFirmware";
})(BootloaderState || (BootloaderState = {}));
class Bootloader {
  static {
    __name(this, "Bootloader");
  }
  constructor(writeSerial, version, options) {
    this.writeSerial = writeSerial;
    this.version = version;
    this.options = new Map(options.map((o) => [o.num, o.option]));
    const uploadOption = options.find((o) => o.option === "upload gbl")?.num;
    if (!uploadOption) {
      throw new import_core.ZWaveError("The bootloader does not support uploading a GBL file!", import_core.ZWaveErrorCodes.Driver_NotSupported);
    }
    this.uploadOption = uploadOption;
    const runOption = options.find((o) => o.option === "run")?.num;
    if (!runOption) {
      throw new import_core.ZWaveError("Could not find run option in bootloader menu!", import_core.ZWaveErrorCodes.Driver_NotSupported);
    }
    this.runOption = runOption;
  }
  writeSerial;
  state = BootloaderState.Menu;
  version;
  options;
  uploadOption;
  runOption;
  async selectOption(option) {
    if (!this.options.has(option))
      return false;
    await this.writeSerial(import_shared.Bytes.from(option.toString(), "ascii"));
    return true;
  }
  findOption(predicate) {
    return [...this.options.entries()].find(([, option]) => predicate(option))?.[0];
  }
  async beginUpload() {
    await this.selectOption(this.uploadOption);
  }
  async runApplication() {
    await this.selectOption(this.runOption);
  }
  async uploadFragment(fragmentNumber, data) {
    const command = import_shared.Bytes.concat([
      import_shared.Bytes.from([
        import_serial.XModemMessageHeaders.SOF,
        fragmentNumber & 255,
        255 - (fragmentNumber & 255)
      ]),
      data,
      new import_shared.Bytes(2)
    ]);
    command.writeUInt16BE((0, import_core.CRC16_CCITT)(data, 0), command.length - 2);
    await this.writeSerial(command);
  }
  async finishUpload() {
    await this.writeSerial(import_shared.Bytes.from([import_serial.XModemMessageHeaders.EOT]));
  }
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  Bootloader,
  BootloaderState
});
//# sourceMappingURL=Bootloader.js.map
