/**
 * @license
 * Copyright 2022-2025 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { CrossReference } from "./CrossReference.js";
class Resource {
  errors;
  asOf;
  until;
  matchTo;
  pics;
  description;
  xref;
  details;
  constructor(resources) {
    if (!resources) {
      return;
    }
    this.description = resources.description;
    this.details = resources.details;
    this.xref = resources.xref ? CrossReference.get(resources.xref) : void 0;
    this.errors = resources.errors;
    this.asOf = resources.asOf;
    this.until = resources.until;
    this.matchTo = resources.matchTo;
    this.pics = resources.pics;
  }
}
class ResourceBundle {
  /**
   * Resource location is relatively expensive because it searches parent hierarchy.  So we cache nodes here.
   *
   * If new resources are added, which is uncommon, we clear the cache.
   */
  #cache;
  #index = {
    resource: void 0,
    children: void 0,
    discriminated: void 0
  };
  get(model) {
    const cached = this.#cache?.get(model);
    if (cached === false) {
      return;
    }
    if (cached) {
      return cached?.resource;
    }
    const node = this.#findNode(model);
    if (!this.#cache) {
      this.#cache = /* @__PURE__ */ new WeakMap();
    }
    this.#cache.set(model, node ?? false);
    return node?.resource;
  }
  add(resource) {
    this.#addNode(resource, this.#index);
    this.#cache = void 0;
  }
  #addNode(item, owner) {
    const key = `${item.tag}:${item.name}`;
    let node = owner.children?.get(key);
    if (!node) {
      node = {};
      if (!owner.children) {
        owner.children = /* @__PURE__ */ new Map();
      }
      owner.children.set(key, node);
    }
    if (item.discriminator) {
      if (node.discriminated) {
        let node2 = node.discriminated.get(item.discriminator);
        if (node2) {
          node = node2;
        } else {
          node2 = {};
          node.discriminated.set(item.discriminator, node2);
          node = node2;
        }
      } else {
        const node2 = {};
        node.discriminated = /* @__PURE__ */ new Map();
        node.discriminated.set(item.discriminator, node2);
        node = node2;
      }
    }
    node.resource = new Resource(item);
    Object.freeze(node.resource);
    if (item.children) {
      for (const child of item.children) {
        this.#addNode(child, node);
      }
    }
  }
  #findNode(model) {
    let parent;
    if (!model.parent || model.parent === model.root) {
      parent = this.#index;
    } else {
      parent = this.#findNode(model.parent);
    }
    if (!parent) {
      return;
    }
    const key = `${model.tag}:${model.name}`;
    const node = parent.children?.get(key);
    if (!node) {
      return;
    }
    if (node.discriminated) {
      return node.discriminated?.get(Resource.discriminatorFor(model));
    }
    return node;
  }
  static default = new ResourceBundle();
}
((Resource2) => {
  function add(named) {
    ResourceBundle.default.add(named);
  }
  Resource2.add = add;
  function discriminatorFor(model) {
    if (model.tag === "requirement") {
      return `${model.conformance ?? ""}:${model.element}`;
    }
    if ("conformance" in model && model.conformance.isEmpty === false) {
      return `${model.conformance}`;
    }
  }
  Resource2.discriminatorFor = discriminatorFor;
})(Resource || (Resource = {}));
export {
  Resource,
  ResourceBundle
};
//# sourceMappingURL=Resource.js.map
