import { anchorIsValid as f } from "./accelbyte-widgets719.mjs";
import { visit as l } from "./accelbyte-widgets649.mjs";
import { ALIAS as h, isAlias as m, isCollection as p, isPair as g } from "./accelbyte-widgets711.mjs";
import { NodeBase as v } from "./accelbyte-widgets726.mjs";
import { toJS as w } from "./accelbyte-widgets716.mjs";
class y extends v {
  constructor(e) {
    super(h), this.source = e, Object.defineProperty(this, "tag", {
      set() {
        throw new Error("Alias nodes cannot have tags");
      }
    });
  }
  resolve(e) {
    let s;
    return l(e, {
      Node: (r, t) => {
        if (t === this)
          return l.BREAK;
        t.anchor === this.source && (s = t);
      }
    }), s;
  }
  toJSON(e, s) {
    if (!s)
      return { source: this.source };
    const { anchors: r, doc: t, maxAliasCount: i } = s, a = this.resolve(t);
    if (!a) {
      const c = `Unresolved alias (the anchor must be set before the alias): ${this.source}`;
      throw new ReferenceError(c);
    }
    let o = r.get(a);
    if (o || (w(a, null, s), o = r.get(a)), !o || o.res === void 0) {
      const c = "This should not happen: Alias anchor was not resolved?";
      throw new ReferenceError(c);
    }
    if (i >= 0 && (o.count += 1, o.aliasCount === 0 && (o.aliasCount = u(t, a, r)), o.count * o.aliasCount > i)) {
      const c = "Excessive alias count indicates a resource exhaustion attack";
      throw new ReferenceError(c);
    }
    return o.res;
  }
  toString(e, s, r) {
    const t = `*${this.source}`;
    if (e) {
      if (f(this.source), e.options.verifyAliasOrder && !e.anchors.has(this.source)) {
        const i = `Unresolved alias (the anchor must be set before the alias): ${this.source}`;
        throw new Error(i);
      }
      if (e.implicitKey)
        return `${t} `;
    }
    return t;
  }
}
function u(n, e, s) {
  if (m(e)) {
    const r = e.resolve(n), t = s && r && s.get(r);
    return t ? t.count * t.aliasCount : 0;
  } else if (p(e)) {
    let r = 0;
    for (const t of e.items) {
      const i = u(n, t, s);
      i > r && (r = i);
    }
    return r;
  } else if (g(e)) {
    const r = u(n, e.key, s), t = u(n, e.value, s);
    return Math.max(r, t);
  }
  return 1;
}
export {
  y as Alias
};
