"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 ModelDiff_exports = {};
__export(ModelDiff_exports, {
  ModelDiff: () => ModelDiff
});
module.exports = __toCommonJS(ModelDiff_exports);
var import_Specification = require("#common/Specification.js");
var import_general = require("@matter/general");
var import_ModelVariantTraversal = require("./ModelVariantTraversal.js");
/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
function ModelDiff(from, to, depth = 2) {
  const traversal = new DiffTraversal(depth);
  return traversal.traverse({ from, to });
}
class DiffTraversal extends import_ModelVariantTraversal.ModelVariantTraversal {
  #detailDepth;
  #currentDepth = 0;
  constructor(depth) {
    super(import_Specification.Specification.REVISION, ["from", "to"]);
    this.#detailDepth = depth;
  }
  visit(variants, recurse) {
    if (variants.map.to === void 0) {
      if (variants.map.from === void 0) {
        return;
      }
      return {
        kind: "delete",
        tag: variants.tag,
        name: variants.name
      };
    }
    if (variants.map.from === void 0) {
      return {
        kind: "add",
        tag: variants.tag,
        name: variants.name
      };
    }
    if (this.#currentDepth >= this.#detailDepth) {
      return;
    }
    this.#currentDepth++;
    const children = recurse().filter((child) => child !== void 0);
    this.#currentDepth--;
    if (!children.length) {
      return;
    }
    if (this.#currentDepth < this.#detailDepth - 1) {
      return {
        kind: "list",
        tag: variants.tag,
        name: variants.name,
        children
      };
    }
    const changes = {};
    for (const child of children) {
      changes[child.tag] = (changes[child.tag] ?? 0) + 1;
    }
    return {
      kind: "summary",
      tag: variants.tag,
      name: variants.name,
      changes
    };
  }
}
((ModelDiff2) => {
  function diagnosticOf(diff) {
    const id = `${diff?.tag}#${diff?.name}`;
    switch (diff?.kind) {
      case "add":
        return import_general.Diagnostic.added(id);
      case "delete":
        return import_general.Diagnostic.deleted(id);
      case "list":
        if (diff.children.length) {
          return [id, import_general.Diagnostic.list(diff.children.map(diagnosticOf))];
        }
        break;
      case "summary":
        const changes = Object.entries(diff.changes).map(([tag, count]) => {
          if (count < 0) {
            return import_general.Diagnostic.deleted(`${-count} ${tag}`);
          }
          if (count > 0) {
            return import_general.Diagnostic.added(`${count} ${tag}`);
          }
          return import_general.Diagnostic.weak(`${0} ${tag}`);
        });
        return [`${id}`, ...changes];
    }
    return import_general.Diagnostic.weak("(unchanged)");
  }
  ModelDiff2.diagnosticOf = diagnosticOf;
})(ModelDiff || (ModelDiff = {}));
//# sourceMappingURL=ModelDiff.js.map
