"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 Lifetime_exports = {};
__export(Lifetime_exports, {
  Lifetime: () => Lifetime
});
module.exports = __toCommonJS(Lifetime_exports);
var import_Diagnostic = require("#log/Diagnostic.js");
var import_DiagnosticPresentation = require("#log/DiagnosticPresentation.js");
var import_DiagnosticSource = require("#log/DiagnosticSource.js");
var import_MatterError = require("#MatterError.js");
var import_Duration = require("#time/Duration.js");
var import_StandardTime = require("#time/StandardTime.js");
var import_Time = require("#time/Time.js");
var import_Timestamp = require("#time/Timestamp.js");
var import_Boot = require("./Boot.js");
/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
function Lifetime(...name) {
  return Lifetime.process.join(...name);
}
class LifetimeImplementation {
  #name;
  #owner;
  #startedAt;
  #details;
  #spans;
  #closing;
  #isClosed = false;
  constructor(name, owner) {
    this.#name = name.length > 1 ? name : name[0];
    this.#startedAt = import_Time.Time.nowMs;
    this.#owner = owner;
    if (owner) {
      owner.spans.add(this);
    }
  }
  get spans() {
    if (!this.#spans) {
      this.#spans = /* @__PURE__ */ new Set();
    }
    return this.#spans;
  }
  get name() {
    return this.#name;
  }
  set name(name) {
    this.#name = name;
  }
  get startedAt() {
    return this.#startedAt;
  }
  get details() {
    return this.#details ?? {};
  }
  get owner() {
    return this.#owner;
  }
  set owner(owner) {
    if (!this.#owner) {
      throw new import_MatterError.InternalError("Cannot move ownership of root lifetime");
    }
    if (this.#owner === owner) {
      return;
    }
    removeSpan(this.owner, this);
    this.#owner = owner;
    this.#owner?.spans.add(this);
  }
  join(...name) {
    return new LifetimeImplementation(name, this);
  }
  closing() {
    if (!this.#closing) {
      this.#closing = this.join("closing");
      const disposeClosing = this.#closing[Symbol.dispose].bind(this.#closing);
      this.#closing[Symbol.dispose] = () => {
        disposeClosing();
        this[Symbol.dispose]();
      };
    }
    return this.#closing;
  }
  get isOpen() {
    return this.#closing === void 0 && !this.#isClosed;
  }
  get isClosing() {
    return this.#closing !== void 0 || this.#isClosed;
  }
  get isClosed() {
    return this.#isClosed;
  }
  get [import_DiagnosticPresentation.DiagnosticPresentation.value]() {
    if (!this.#owner) {
      return import_Diagnostic.Diagnostic.node("\u{1F331}", "Lifetimes", {
        children: this.spans
      });
    }
    const header = [this.#name];
    if (this.isClosed) {
      header.push(import_Diagnostic.Diagnostic.weak("(zombie)"));
    }
    const details = {
      up: import_Duration.Duration.format(import_Timestamp.Timestamp.delta(this.startedAt, import_Time.Time.nowMs)),
      ...this.#details
    };
    header.push(import_Diagnostic.Diagnostic.dict(details));
    const result = [header];
    if (this.#spans?.size) {
      result.push(import_Diagnostic.Diagnostic.list(this.spans));
    }
    return result;
  }
  [Symbol.dispose]() {
    if (!this.#owner) {
      return;
    }
    this.#isClosed = true;
    if (this.#spans?.size) {
      return;
    }
    removeSpan(this.#owner, this);
  }
}
let process = new LifetimeImplementation(["process"]);
import_DiagnosticSource.DiagnosticSource.add(process);
function removeSpan(owner, span) {
  if (!owner) {
    return;
  }
  owner.spans.delete(span);
  if (owner.isClosed && !owner.spans?.size) {
    owner[Symbol.dispose]();
  }
}
((Lifetime2) => {
  function of(subject) {
    return subject?.[Lifetime2.owner] ?? Lifetime2.process;
  }
  Lifetime2.of = of;
  Lifetime2.owner = /* @__PURE__ */ Symbol("owner");
})(Lifetime || (Lifetime = {}));
Object.defineProperties(Lifetime, {
  process: {
    get() {
      return process;
    }
  },
  mock: {
    get() {
      return new LifetimeImplementation(["mock"]);
    }
  }
});
import_Boot.Boot.init(() => {
  process = new LifetimeImplementation(["process"]);
  import_DiagnosticSource.DiagnosticSource.add(process);
}, "state");
//# sourceMappingURL=Lifetime.js.map
