import { i as m, c as x, a as D, d as b, e as A, g as M, f as S, m as v, L as F, E as L } from "./language-defaults-base.js";
import { supportedLocales as k, fetchT9nStringsBundle as E } from "@arcgis/toolkit/intl";
import { g as y } from "./runtime.js";
import { CompletionItemKind as w, InsertTextFormat as u, InsertTextMode as p } from "vscode-languageserver-types";
import { getDeclaredPixelMembers as I } from "@arcgis/core/applications/Components/arcadeEditorUtils.js";
/*! All material copyright Esri, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/5.0/esri/copyright.txt for details.
v5.0.0-next.112 */
async function C(e) {
  const { apiVersion: r, bundles: t, hiddenApiItems: i } = e.toEditorProfileDefinition(), n = await h(e.dictionaryVariables);
  return { apiVersion: r, bundles: t, variables: n, hiddenApiItems: i?.map((s) => s.toLowerCase()) };
}
async function h(e, r = w.Variable) {
  return await Promise.all(
    e.map(async (t) => {
      switch (t.type) {
        case "dictionary":
          return await K(t, r);
        case "pixel":
          return await B(t, r);
        // Voxel is equivalent to features in regards to the languageservice.
        // They both have equivalent fields, but some voxel fields are different types (arrays)
        // than what is reported in .fields, so in the sidebar we treat a bit differently.
        // In autocomplete we don't differentiate types, so we can use the same logic as features.
        case "voxel":
        case "feature":
          return await j(t, r);
        default:
          return $(t, r);
      }
    })
  );
}
function $(e, r) {
  const { name: t, type: i } = e, n = e.getDescription();
  return {
    name: t,
    description: n,
    type: i,
    completion: {
      label: t,
      detail: t,
      insertText: t,
      insertTextMode: p.asIs,
      insertTextFormat: u.PlainText,
      kind: r,
      documentation: { kind: "markdown", value: n }
    }
  };
}
async function j(e, r) {
  const t = await e.loadSource(), { name: i } = e, n = e.getDescription(), s = {
    label: i,
    detail: i,
    insertText: i,
    insertTextMode: p.asIs,
    insertTextFormat: u.PlainText,
    kind: r
  }, o = {
    name: i,
    description: n,
    type: "dictionary",
    properties: [],
    completion: s
  };
  if (!t)
    return o;
  const [a, c] = S(t.fields, n, !0);
  return o.properties = a, s.documentation = { kind: "markdown", value: c }, o;
}
async function B(e, r) {
  const t = await e.loadSource(), i = e.toProfileVariableDefinition();
  if (i.type !== "pixel")
    throw new Error("Incorrect definition passed to pixel variable");
  const { name: n } = e, s = e.getDescription(), o = {
    label: n,
    detail: n,
    insertText: n,
    insertTextMode: p.asIs,
    insertTextFormat: u.PlainText,
    kind: r
  }, a = {
    name: n,
    description: s,
    type: "dictionary",
    properties: [],
    completion: o
  };
  if (!t || !i.definition)
    return a;
  const c = await I(t), [g, P] = v(c, s);
  return a.properties = g, o.documentation = { kind: "markdown", value: P }, a;
}
async function K(e, r) {
  const { name: t, dictionaryVariables: i } = e, n = e.getDescription(), s = i.reduce((o, a) => {
    o !== "" && (o += `  
  
`), o += `**${a.name}**  
${a.type}`;
    const c = a.getDescription();
    return c && (o += `  
${c}`), o;
  }, n);
  return {
    name: t,
    description: n,
    type: "dictionary",
    properties: await h(i, w.Field),
    completion: {
      label: t,
      detail: t,
      insertText: t,
      insertTextMode: p.asIs,
      insertTextFormat: u.PlainText,
      kind: r,
      documentation: { kind: "markdown", value: s }
    }
  };
}
async function f(e = "en") {
  const r = T.get(e);
  if (r)
    return r;
  if (!k.has(e))
    return await f("en");
  try {
    const t = await fetch(y(`./assets/arcade-language/profiles/arcade-profiles.t9n.${e}.json`));
    return t.ok ? _(e, await t.json()) : e === "en" ? null : await f("en");
  } catch {
    return null;
  }
}
const T = /* @__PURE__ */ new Map();
function _(e, r) {
  const t = /* @__PURE__ */ new Map();
  return r.forEach((i) => {
    t.set(i.id, i);
  }), T.set(e, t), t;
}
async function q(e, r = "en") {
  return (await f(r))?.get(e) ?? null;
}
function z(e) {
  return !!e && typeof e == "object" && "additionalVariables" in e && Array.isArray(e.additionalVariables);
}
function G(e) {
  return e?.map(d);
}
function d(e) {
  switch (e.type) {
    case "dictionary":
      return {
        ...e,
        type: e.type,
        properties: G(e.properties)
      };
    case "array":
      return {
        ...e,
        type: e.type,
        elementType: { type: "number", name: "number" }
      };
    default:
      return { ...e, type: e.type };
  }
}
async function H(e, r = "en") {
  if (!m(e))
    return;
  const t = await q(e.id, r);
  if (!t)
    return;
  const i = {
    bundles: [...t.bundles],
    variables: [],
    hiddenApiItems: e.hiddenApiItems?.map((n) => n.toLowerCase())
  };
  return t.variables.forEach((n) => {
    if (e.disabledVariables?.includes(n.name))
      return;
    const s = e.definitions[n.name];
    switch (n.type) {
      case "dictionary":
        return i.variables.push(
          d({
            ...n,
            type: n.type,
            properties: Array.isArray(s) ? [...s] : n.properties
          })
        );
      case "feature":
        return M(s) ? i.variables.push({ ...n, type: "feature", definition: s }) : void 0;
      case "pixel":
        return A(s) ? i.variables.push({ ...n, type: n.type, definition: s }) : void 0;
      case "voxel":
        return b(s) ? i.variables.push({ ...n, type: n.type, definition: s }) : void 0;
      case "featureSet":
        return D(s) ? i.variables.push({ ...n, type: n.type, definition: s }) : void 0;
      case "featureSetCollection":
        return x(s) ? i.variables.push({ ...n, type: n.type, definition: s }) : void 0;
      default:
        return i.variables.push(d(n));
    }
  }), z(e) && i.variables.push(...e.additionalVariables ?? []), i;
}
class J extends F {
  constructor() {
    super("arcade", {
      apiPath: "./assets/arcade-language/api",
      apiPrefix: "arcade-api.t9n."
    });
  }
  /**
   * Create an EditorProfile for the given model id using the given definition and locale.
   * The EditorProfile is used by the the Arcade Language service as well by the coding components.
   * The definition can be a pre-defined profile or an editor profile definition.
   * If the locale is not provided then the 'en' locale is used.
   * @param modelId The model id for which to create the context.
   * @param definition The definition to use for the model context.
   * @param locale The locale to use for the model context.
   * @returns The EditorProfile for the model.
   */
  async setProfileForModel(r, t, i = { locale: "en" }) {
    m(t) && (t = await H(t, i.locale));
    const n = await E(
      i.locale,
      y("./assets/editor-profile/t9n"),
      "messages."
    );
    if (!n)
      throw new Error(`Failed to load the language bundle for ${i.locale}`);
    this.disposeForModel(r);
    const s = this._getApiKey(r), o = new L(t, n);
    this._modelToProfileMap.set(s, o);
    const a = await C(o);
    this.updateApiContextForModel(r, {
      locale: i.locale,
      profile: a,
      snippets: i.snippets
    });
  }
}
const l = new J(), W = {
  setProfileForModel: l.setProfileForModel.bind(l),
  getApiLibraryForModel: l.getApiLibraryForModel.bind(l)
};
export {
  W as a,
  l as b
};
