"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 Duration_exports = {};
__export(Duration_exports, {
  Duration: () => Duration
});
module.exports = __toCommonJS(Duration_exports);
var import_math = require("alcalzone-shared/math");
var import_ZWaveError = require("../error/ZWaveError.js");
const durationStringRegex = /^(?:(?<hoursStr>\d+)h)?(?:(?<minutesStr>\d+)m)?(?:(?<secondsStr>\d+)s)?$/i;
class Duration {
  static {
    __name(this, "Duration");
  }
  unit;
  constructor(value, unit) {
    this.unit = unit;
    switch (unit) {
      case "minutes":
        if (value === 0)
          this.unit = "seconds";
        break;
      case "unknown":
      case "default":
        value = 0;
        break;
    }
    this.value = value;
  }
  _value;
  get value() {
    return this._value;
  }
  set value(v) {
    this._value = (0, import_math.clamp)(v, 0, 127);
  }
  static unknown() {
    return new Duration(0, "unknown");
  }
  static default() {
    return new Duration(0, "default");
  }
  static isDuration(value) {
    return typeof value === "object" && value != null && "value" in value && typeof value.value === "number" && "unit" in value && typeof value.unit === "string";
  }
  /** Parses a duration as represented in Report commands */
  static parseReport(payload) {
    if (payload == void 0)
      return void 0;
    if (payload === 255)
      return void 0;
    if (payload === 254)
      return Duration.unknown();
    const isMinutes = !!(payload & 128);
    const value = (payload & 127) + (isMinutes ? 1 : 0);
    return new Duration(value, isMinutes ? "minutes" : "seconds");
  }
  /** Parses a duration as represented in Set commands */
  static parseSet(payload) {
    if (payload == void 0)
      return void 0;
    if (payload === 255)
      return Duration.default();
    const isMinutes = !!(payload & 128);
    const value = (payload & 127) + (isMinutes ? 1 : 0);
    return new Duration(value, isMinutes ? "minutes" : "seconds");
  }
  /**
   * Parses a user-friendly duration string in the format "Xs", "Xm", "XhYm" or "XmYs", for example "10m20s".
   * If that cannot be exactly represented as a Z-Wave duration, the nearest possible representation will be used.
   */
  static parseString(text) {
    if (!text.length)
      return void 0;
    if (text === "default")
      return Duration.default();
    const match = durationStringRegex.exec(text);
    if (!match)
      return void 0;
    const { hoursStr, minutesStr, secondsStr } = match.groups;
    const hours = hoursStr ? parseInt(hoursStr) : 0;
    const minutes = minutesStr ? parseInt(minutesStr) : 0;
    const seconds = secondsStr ? parseInt(secondsStr) : 0;
    if (hours) {
      if (hours * 60 + minutes <= 127) {
        return new Duration(60 * hours + minutes, "minutes");
      }
    } else if (minutes * 60 + seconds > 127) {
      return new Duration(minutes + Math.round(seconds / 60), "minutes");
    } else {
      return new Duration(minutes * 60 + seconds, "seconds");
    }
  }
  static from(input) {
    if (input instanceof Duration) {
      return input;
    } else if (Duration.isDuration(input)) {
      return new Duration(input.value, input.unit);
    } else if (input) {
      return Duration.parseString(input);
    } else {
      return void 0;
    }
  }
  /** Serializes a duration for a Set command */
  serializeSet() {
    if (this.unit === "default")
      return 255;
    if (this.unit === "unknown") {
      throw new import_ZWaveError.ZWaveError("Set commands don't support unknown durations", import_ZWaveError.ZWaveErrorCodes.CC_Invalid);
    }
    const isMinutes = this.unit === "minutes";
    let payload = isMinutes ? 128 : 0;
    payload += this._value - (isMinutes ? 1 : 0) & 127;
    return payload;
  }
  /** Serializes a duration for a Report command */
  serializeReport() {
    if (this.unit === "unknown")
      return 254;
    const isMinutes = this.unit === "minutes";
    let payload = isMinutes ? 128 : 0;
    payload += this._value - (isMinutes ? 1 : 0) & 127;
    return payload;
  }
  toJSON() {
    if (this.unit === "default" || this.unit === "unknown") {
      return this.unit;
    }
    return {
      value: this.value,
      unit: this.unit
    };
  }
  toMilliseconds() {
    switch (this.unit) {
      case "minutes":
        return this._value * 6e4;
      case "seconds":
        return this._value * 1e3;
    }
  }
  toString() {
    let ret = "";
    switch (this.unit) {
      case "minutes":
        if (this._value >= 60) {
          ret += `${Math.floor(this._value / 60)}h`;
        }
        ret += `${this._value % 60}m`;
        return ret;
      case "seconds":
        if (this._value >= 60) {
          ret += `${Math.floor(this._value / 60)}m`;
        }
        ret += `${this._value % 60}s`;
        return ret;
      default:
        return this.unit;
    }
  }
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  Duration
});
//# sourceMappingURL=Duration.js.map
