/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { Internal } from "../state/managed/Internal.js";
class GlobalConfig {
  #supervision;
  #children;
  get supervision() {
    return this.#supervision;
  }
  set supervision(supervision) {
    this.#supervision = supervision;
  }
  child(key) {
    if (this.#children === void 0) {
      this.#children = /* @__PURE__ */ new Map();
    }
    let child = this.#children.get(key);
    if (child === void 0) {
      child = new GlobalConfig();
      this.#children.set(key, child);
    }
    return child;
  }
  readonlyChild(key) {
    return this.#children?.get(key);
  }
  /**
   * Iterate over all existing children.
   */
  forEachChild(fn) {
    this.#children?.forEach((child, key) => fn(key, child));
  }
}
class LocalConfig {
  #global;
  #localSupervision;
  #hasLocalSupervision = false;
  #children;
  constructor(global) {
    this.#global = global;
  }
  get supervision() {
    if (this.#hasLocalSupervision) {
      return this.#localSupervision;
    }
    return this.#global.supervision;
  }
  set supervision(supervision) {
    this.#localSupervision = supervision;
    this.#hasLocalSupervision = true;
  }
  child(key) {
    if (this.#children === void 0) {
      this.#children = /* @__PURE__ */ new Map();
    }
    let child = this.#children.get(key);
    if (child === void 0) {
      child = new LocalConfig(this.#global.child(key));
      this.#children.set(key, child);
    }
    return child;
  }
  readonlyChild(key) {
    const globalChild = this.#global.readonlyChild(key);
    if (globalChild === void 0) {
      return this.#children?.get(key);
    }
    let child = this.#children?.get(key);
    if (child === void 0) {
      child = new LocalConfig(globalChild);
      if (this.#children === void 0) {
        this.#children = /* @__PURE__ */ new Map();
      }
      this.#children.set(key, child);
    }
    return child;
  }
}
function maybeConfigOf(objectOrConstructor, fieldName) {
  if (typeof objectOrConstructor === "function") {
    return maybeConfigOfConstructor(objectOrConstructor.prototype, fieldName);
  }
  return maybeConfigOfObject(objectOrConstructor, fieldName);
}
function maybeConfigOfObject(object, fieldName) {
  let config;
  const ref = object[Internal.reference];
  if (ref) {
    config = ref.supervisionConfig;
  } else {
    config = bareObjectConfigs.get(object);
  }
  if (config === void 0) {
    return void 0;
  }
  if (fieldName === void 0) {
    return config;
  }
  return config.readonlyChild(fieldName)?.supervision;
}
const bareObjectConfigs = /* @__PURE__ */ new WeakMap();
const commandSupervisionConfigs = /* @__PURE__ */ new WeakMap();
function maybeConfigOfConstructor(prototype, methodName) {
  const chain = [];
  let current = prototype;
  while (current !== null) {
    const map = commandSupervisionConfigs.get(current);
    if (map !== void 0) {
      const config = map.get(methodName);
      if (config !== void 0) {
        chain.push(config);
      }
    }
    current = Object.getPrototypeOf(current);
  }
  if (chain.length === 0) {
    return void 0;
  }
  if (chain.length === 1) {
    return chain[0];
  }
  return mergeConfigs(chain.reverse());
}
function mergeConfigs(configs) {
  const merged = new GlobalConfig();
  for (const source of configs) {
    mergeConfigInto(merged, source);
  }
  return merged;
}
function mergeConfigInto(target, source) {
  if (source.supervision !== void 0) {
    target.supervision = { ...target.supervision, ...source.supervision };
  }
  source.forEachChild((key, child) => {
    mergeConfigInto(target.child(key), child);
  });
}
export {
  GlobalConfig,
  LocalConfig,
  bareObjectConfigs,
  commandSupervisionConfigs,
  maybeConfigOf,
  maybeConfigOfConstructor
};
//# sourceMappingURL=SupervisionConfig.js.map
