"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 AddNodeToNetworkRequest_exports = {};
__export(AddNodeToNetworkRequest_exports, {
  AddNodeDSKToNetworkRequest: () => AddNodeDSKToNetworkRequest,
  AddNodeStatus: () => AddNodeStatus,
  AddNodeToNetworkRequest: () => AddNodeToNetworkRequest,
  AddNodeToNetworkRequestBase: () => AddNodeToNetworkRequestBase,
  AddNodeToNetworkRequestStatusReport: () => AddNodeToNetworkRequestStatusReport,
  AddNodeType: () => AddNodeType,
  EnableSmartStartListenRequest: () => EnableSmartStartListenRequest,
  computeNeighborDiscoveryTimeout: () => computeNeighborDiscoveryTimeout
});
module.exports = __toCommonJS(AddNodeToNetworkRequest_exports);
var import_tslib = require("tslib");
var import_core = require("@zwave-js/core");
var import_serial = require("@zwave-js/serial");
var import_shared = require("@zwave-js/shared");
var AddNodeType;
(function(AddNodeType2) {
  AddNodeType2[AddNodeType2["Any"] = 1] = "Any";
  AddNodeType2[AddNodeType2["Controller"] = 2] = "Controller";
  AddNodeType2[AddNodeType2["Slave"] = 3] = "Slave";
  AddNodeType2[AddNodeType2["Existing"] = 4] = "Existing";
  AddNodeType2[AddNodeType2["Stop"] = 5] = "Stop";
  AddNodeType2[AddNodeType2["StopControllerReplication"] = 6] = "StopControllerReplication";
  AddNodeType2[AddNodeType2["SmartStartDSK"] = 8] = "SmartStartDSK";
  AddNodeType2[AddNodeType2["SmartStartListen"] = 9] = "SmartStartListen";
})(AddNodeType || (AddNodeType = {}));
var AddNodeStatus;
(function(AddNodeStatus2) {
  AddNodeStatus2[AddNodeStatus2["Ready"] = 1] = "Ready";
  AddNodeStatus2[AddNodeStatus2["NodeFound"] = 2] = "NodeFound";
  AddNodeStatus2[AddNodeStatus2["AddingSlave"] = 3] = "AddingSlave";
  AddNodeStatus2[AddNodeStatus2["AddingController"] = 4] = "AddingController";
  AddNodeStatus2[AddNodeStatus2["ProtocolDone"] = 5] = "ProtocolDone";
  AddNodeStatus2[AddNodeStatus2["Done"] = 6] = "Done";
  AddNodeStatus2[AddNodeStatus2["Failed"] = 7] = "Failed";
})(AddNodeStatus || (AddNodeStatus = {}));
var AddNodeFlags;
(function(AddNodeFlags2) {
  AddNodeFlags2[AddNodeFlags2["HighPower"] = 128] = "HighPower";
  AddNodeFlags2[AddNodeFlags2["NetworkWide"] = 64] = "NetworkWide";
  AddNodeFlags2[AddNodeFlags2["ProtocolLongRange"] = 32] = "ProtocolLongRange";
})(AddNodeFlags || (AddNodeFlags = {}));
function computeNeighborDiscoveryTimeout(host, nodeType) {
  const allNodes = host.getAllNodes().filter((n) => !(0, import_core.isLongRangeNodeId)(n.id));
  const numListeningNodes = allNodes.filter((n) => n.isListening).length;
  const numFlirsNodes = allNodes.filter((n) => n.isFrequentListening).length;
  const numNodes = allNodes.length;
  return 76e3 + numListeningNodes * 217 + numFlirsNodes * 3517 + (nodeType === import_core.NodeType.Controller ? numNodes * 732 : 0);
}
__name(computeNeighborDiscoveryTimeout, "computeNeighborDiscoveryTimeout");
let AddNodeToNetworkRequestBase = (() => {
  let _classDecorators = [(0, import_serial.messageTypes)(import_serial.MessageType.Request, import_serial.FunctionType.AddNodeToNetwork), (0, import_serial.priority)(import_core.MessagePriority.Controller)];
  let _classDescriptor;
  let _classExtraInitializers = [];
  let _classThis;
  let _classSuper = import_serial.Message;
  var AddNodeToNetworkRequestBase2 = class extends _classSuper {
    static {
      __name(this, "AddNodeToNetworkRequestBase");
    }
    static {
      _classThis = this;
    }
    static {
      const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
      (0, import_tslib.__esDecorate)(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
      AddNodeToNetworkRequestBase2 = _classThis = _classDescriptor.value;
      if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
      (0, import_tslib.__runInitializers)(_classThis, _classExtraInitializers);
    }
    static from(raw, ctx) {
      if (ctx.origin === import_serial.MessageOrigin.Host) {
        return AddNodeToNetworkRequest.from(raw, ctx);
      } else {
        return AddNodeToNetworkRequestStatusReport.from(raw, ctx);
      }
    }
  };
  return AddNodeToNetworkRequestBase2 = _classThis;
})();
function testCallbackForAddNodeRequest(sent, received) {
  if (!(received instanceof AddNodeToNetworkRequestStatusReport)) {
    return false;
  }
  switch (sent.addNodeType) {
    case AddNodeType.Any:
    case AddNodeType.Controller:
    case AddNodeType.Slave:
    case AddNodeType.Existing:
      return received.status === AddNodeStatus.Ready || received.status === AddNodeStatus.Failed;
    case AddNodeType.Stop:
    case AddNodeType.StopControllerReplication:
      return received.status === AddNodeStatus.Done || received.status === AddNodeStatus.Failed;
    default:
      return false;
  }
}
__name(testCallbackForAddNodeRequest, "testCallbackForAddNodeRequest");
let AddNodeToNetworkRequest = (() => {
  let _classDecorators = [(0, import_serial.expectedCallback)(testCallbackForAddNodeRequest)];
  let _classDescriptor;
  let _classExtraInitializers = [];
  let _classThis;
  let _classSuper = AddNodeToNetworkRequestBase;
  var AddNodeToNetworkRequest2 = class extends _classSuper {
    static {
      __name(this, "AddNodeToNetworkRequest");
    }
    static {
      _classThis = this;
    }
    static {
      const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
      (0, import_tslib.__esDecorate)(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
      AddNodeToNetworkRequest2 = _classThis = _classDescriptor.value;
      if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
      (0, import_tslib.__runInitializers)(_classThis, _classExtraInitializers);
    }
    constructor(options) {
      super(options);
      this.addNodeType = options.addNodeType;
      this.highPower = !!options.highPower;
      this.networkWide = !!options.networkWide;
    }
    static from(raw, _ctx) {
      const highPower = !!(raw.payload[0] & AddNodeFlags.HighPower);
      const networkWide = !!(raw.payload[0] & AddNodeFlags.NetworkWide);
      const addNodeType = raw.payload[0] & 15;
      const callbackId = raw.payload[1];
      return new this({
        callbackId,
        addNodeType,
        highPower,
        networkWide
      });
    }
    /** The type of node to add */
    addNodeType;
    /** Whether to use high power */
    highPower = false;
    /** Whether to include network wide */
    networkWide = false;
    serialize(ctx) {
      this.assertCallbackId();
      let data = this.addNodeType || AddNodeType.Any;
      if (this.highPower)
        data |= AddNodeFlags.HighPower;
      if (this.networkWide)
        data |= AddNodeFlags.NetworkWide;
      this.payload = import_shared.Bytes.from([data, this.callbackId]);
      return super.serialize(ctx);
    }
    toLogEntry() {
      let message;
      if (this.addNodeType === AddNodeType.Stop) {
        message = { action: "Stop" };
      } else {
        message = {
          "node type": (0, import_shared.getEnumMemberName)(AddNodeType, this.addNodeType)
        };
      }
      message = {
        ...message,
        "high power": this.highPower,
        "network wide": this.networkWide
      };
      if (this.hasCallbackId()) {
        message["callback id"] = this.callbackId;
      }
      return {
        ...super.toLogEntry(),
        message
      };
    }
  };
  return AddNodeToNetworkRequest2 = _classThis;
})();
class EnableSmartStartListenRequest extends AddNodeToNetworkRequestBase {
  static {
    __name(this, "EnableSmartStartListenRequest");
  }
  serialize(ctx) {
    const control = AddNodeType.SmartStartListen | AddNodeFlags.NetworkWide;
    this.callbackId = 0;
    this.payload = import_shared.Bytes.from([control, this.callbackId]);
    return super.serialize(ctx);
  }
  toLogEntry() {
    return {
      ...super.toLogEntry(),
      message: {
        action: "Enable Smart Start listening mode"
      }
    };
  }
}
function testCallbackForAddNodeDSKRequest(sent, received) {
  if (!(received instanceof AddNodeToNetworkRequestStatusReport)) {
    return false;
  }
  return received.status === AddNodeStatus.Ready || received.status === AddNodeStatus.Failed;
}
__name(testCallbackForAddNodeDSKRequest, "testCallbackForAddNodeDSKRequest");
let AddNodeDSKToNetworkRequest = (() => {
  let _classDecorators = [(0, import_serial.expectedCallback)(testCallbackForAddNodeDSKRequest)];
  let _classDescriptor;
  let _classExtraInitializers = [];
  let _classThis;
  let _classSuper = AddNodeToNetworkRequestBase;
  var AddNodeDSKToNetworkRequest2 = class extends _classSuper {
    static {
      __name(this, "AddNodeDSKToNetworkRequest");
    }
    static {
      _classThis = this;
    }
    static {
      const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
      (0, import_tslib.__esDecorate)(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
      AddNodeDSKToNetworkRequest2 = _classThis = _classDescriptor.value;
      if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
      (0, import_tslib.__runInitializers)(_classThis, _classExtraInitializers);
    }
    constructor(options) {
      super(options);
      this.nwiHomeId = options.nwiHomeId;
      this.authHomeId = options.authHomeId;
      this.highPower = !!options.highPower;
      this.networkWide = !!options.networkWide;
      this.protocol = options.protocol ?? import_core.Protocols.ZWave;
    }
    /** The home IDs of node to add */
    nwiHomeId;
    authHomeId;
    /** Whether to use high power */
    highPower;
    /** Whether to include network wide */
    networkWide;
    /** Whether to include as long-range or not */
    protocol;
    serialize(ctx) {
      this.assertCallbackId();
      let control = AddNodeType.SmartStartDSK;
      if (this.highPower)
        control |= AddNodeFlags.HighPower;
      if (this.networkWide)
        control |= AddNodeFlags.NetworkWide;
      if (this.protocol === import_core.Protocols.ZWaveLongRange) {
        control |= AddNodeFlags.ProtocolLongRange;
      }
      this.payload = import_shared.Bytes.concat([
        [control, this.callbackId],
        this.nwiHomeId,
        this.authHomeId
      ]);
      return super.serialize(ctx);
    }
    toLogEntry() {
      const message = {
        action: "Add Smart Start node",
        "NWI Home ID": (0, import_shared.buffer2hex)(this.nwiHomeId),
        "high power": this.highPower,
        "network wide": this.networkWide,
        protocol: this.protocol === import_core.Protocols.ZWaveLongRange ? "Z-Wave Long Range" : "Z-Wave Classic"
      };
      if (this.hasCallbackId()) {
        message["callback id"] = this.callbackId;
      }
      return {
        ...super.toLogEntry(),
        message
      };
    }
  };
  return AddNodeDSKToNetworkRequest2 = _classThis;
})();
class AddNodeToNetworkRequestStatusReport extends AddNodeToNetworkRequestBase {
  static {
    __name(this, "AddNodeToNetworkRequestStatusReport");
  }
  constructor(options) {
    super(options);
    this.status = options.status;
    if ("nodeId" in options) {
      this.statusContext = { nodeId: options.nodeId };
    } else if ("nodeInfo" in options) {
      this.statusContext = options.nodeInfo;
    }
  }
  static from(raw, ctx) {
    const callbackId = raw.payload[0];
    const status = raw.payload[1];
    switch (status) {
      case AddNodeStatus.Ready:
      case AddNodeStatus.NodeFound:
      case AddNodeStatus.ProtocolDone:
      case AddNodeStatus.Failed:
        return new this({
          callbackId,
          status
        });
      case AddNodeStatus.Done: {
        const { nodeId } = (0, import_core.parseNodeID)(raw.payload, ctx.nodeIdType, 2);
        return new this({
          callbackId,
          status,
          nodeId
        });
      }
      case AddNodeStatus.AddingController:
      case AddNodeStatus.AddingSlave: {
        const nodeInfo = (0, import_core.parseNodeUpdatePayload)(raw.payload.subarray(2), ctx.nodeIdType);
        return new this({
          callbackId,
          status,
          nodeInfo
        });
      }
    }
  }
  isOK() {
    return this.status !== AddNodeStatus.Failed;
  }
  status;
  statusContext;
  serialize(ctx) {
    this.assertCallbackId();
    this.payload = import_shared.Bytes.from([this.callbackId, this.status]);
    if (this.statusContext?.basicDeviceClass != void 0) {
      this.payload = import_shared.Bytes.concat([
        this.payload,
        (0, import_core.encodeNodeUpdatePayload)(this.statusContext, ctx.nodeIdType)
      ]);
    } else if (this.status === AddNodeStatus.Done && this.statusContext?.nodeId != void 0) {
      this.payload = import_shared.Bytes.concat([
        this.payload,
        (0, import_core.encodeNodeID)(this.statusContext.nodeId, ctx.nodeIdType)
      ]);
    }
    return super.serialize(ctx);
  }
  toLogEntry() {
    return {
      ...super.toLogEntry(),
      message: {
        status: (0, import_shared.getEnumMemberName)(AddNodeStatus, this.status),
        "callback id": this.callbackId ?? "(not set)"
      }
    };
  }
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  AddNodeDSKToNetworkRequest,
  AddNodeStatus,
  AddNodeToNetworkRequest,
  AddNodeToNetworkRequestBase,
  AddNodeToNetworkRequestStatusReport,
  AddNodeType,
  EnableSmartStartListenRequest,
  computeNeighborDiscoveryTimeout
});
//# sourceMappingURL=AddNodeToNetworkRequest.js.map
