import x, { setLogLevel as L, ExtensionSession as ee, registerJsCallBatch as re } from "./extension_js.js";
const I = {
  trace: 0,
  debug: 1,
  info: 2,
  warn: 3,
  error: 4,
  none: 5
}, te = [
  "trace",
  "debug",
  "info",
  "warn",
  "error",
  "none"
];
function se(r) {
  const e = Math.max(0, Math.min(5, Math.round(r)));
  return te[e] ?? "error";
}
let P = "trace", C = null;
function ne(r) {
  P = r, C && C(I[r]);
}
function oe(r) {
  C = r, r(I[P]);
}
function ae(r) {
  return I[r] >= I[P];
}
function V(r, e = "info") {
  var s;
  if (r === null) return "null";
  if (r === void 0) return "undefined";
  if (typeof r == "string") return r;
  if (typeof r == "number" || typeof r == "boolean")
    return String(r);
  if (typeof r == "bigint") return `${r}n`;
  if (r instanceof Error) {
    const t = e === "debug" || e === "trace" ? r.stack : (s = r.stack) == null ? void 0 : s.split(`
`)[0];
    return JSON.stringify({ message: r.message, name: r.name, stack: t });
  }
  if (typeof r == "function") return "[Function]";
  if (typeof r == "symbol") return String(r);
  if (typeof r == "object")
    try {
      return JSON.stringify(r);
    } catch (t) {
      return t instanceof TypeError && t.message.includes("circular") ? "[Circular]" : `[Unserializable: ${t instanceof Error ? t.message : String(t)}]`;
    }
  return String(r);
}
function ie(r) {
  return `[extension-js][${r}]`;
}
function le(r, e) {
  if (!r) return "";
  const s = [];
  try {
    for (const [t, n] of Object.entries(r))
      s.push(`${t}=${V(n, e)}`);
  } catch {
    return " metadata=[unreadable]";
  }
  return s.length > 0 ? ` ${s.join(" ")}` : "";
}
function b(r, e) {
  return e.length === 0 ? { event: r } : e.length === 1 && typeof e[0] == "object" && e[0] !== null && !Array.isArray(e[0]) ? { event: r, metadata: e[0] } : {
    event: r,
    metadata: { _args: e.map((s) => V(s)).join(" ") }
  };
}
class $ {
  constructor(e = "root") {
    this.namespace = e;
  }
  log(e, s, t) {
    try {
      if (!ae(e)) return;
      const n = ie(this.namespace), a = le(t, e), i = `${n} ${s}${a}`;
      switch (e) {
        case "trace":
        case "debug":
        case "info":
          console.log(i);
          break;
        case "warn":
          console.warn(i);
          break;
        case "error":
          console.error(i);
          break;
        case "none":
          break;
        default: {
          const o = e;
          break;
        }
      }
    } catch {
    }
  }
  trace(e, ...s) {
    const { event: t, metadata: n } = b(e, s);
    this.log("trace", t, n);
  }
  debug(e, ...s) {
    const { event: t, metadata: n } = b(e, s);
    this.log("debug", t, n);
  }
  info(e, ...s) {
    const { event: t, metadata: n } = b(e, s);
    this.log("info", t, n);
  }
  warn(e, ...s) {
    const { event: t, metadata: n } = b(e, s);
    this.log("warn", t, n);
  }
  error(e, ...s) {
    const { event: t, metadata: n } = b(e, s);
    this.log("error", t, n);
  }
  child(e) {
    return new $(`${this.namespace}.${e}`);
  }
  timer(e, s, t = "info") {
    const n = typeof performance < "u" && performance.now, a = n ? performance.now() : Date.now();
    return (i) => {
      try {
        const o = n ? performance.now() : Date.now(), g = Math.round(o - a), u = {
          ...s,
          ...i,
          duration_ms: g
        };
        this.log(t, e, u);
      } catch {
      }
    };
  }
}
const l = new $("root"), ce = /* @__PURE__ */ new Set();
function ue(r) {
  return ce.has(r);
}
const J = /* @__PURE__ */ new Map();
function de(r, e) {
  J.set(r, e);
}
function fe(r) {
  return J.get(r);
}
function ge(r) {
  return r.startsWith("tab_") ? "required" : "active";
}
function pe(r) {
  return r === "content-script" ? "content-script" : r === "main-thread" ? "main-thread" : r === "worker" ? "worker:default" : r.startsWith("worker:") ? r : "main-thread";
}
function me(r, e) {
  return e !== "main-thread" ? e : ue(r) ? "content-script" : e;
}
function ye(r, e) {
  return {
    endpoint: pe(me(r, e)),
    tabPolicy: ge(r)
  };
}
function he(r) {
  for (const e of r)
    de(e.action, ye(e.action, e.owner));
}
function k(r) {
  return r == null ? {} : r instanceof Map ? Object.fromEntries(
    [...r.entries()].map(([e, s]) => [e, k(s)])
  ) : Array.isArray(r) ? r.map(k) : r;
}
function Ee(r) {
  return {
    action: r.action,
    namespace: r.namespace,
    name: r.name,
    publicName: r.publicName,
    description: r.description,
    fields: r.fields,
    aliases: (r.aliases ?? []).map((e) => ({
      namespace: e.namespace,
      name: e.name,
      fields: e.fields
    })),
    paramsDoc: r.paramsDoc.map((e) => ({
      name: e.name,
      type: e.type,
      required: e.required,
      description: e.description
    })),
    returnsDoc: {
      type: r.returnsDoc.type,
      description: r.returnsDoc.description
    },
    errorCode: r.errorCode,
    errorCategory: r.errorCategory ?? null,
    permission: r.permission ?? null,
    example: r.example ?? null,
    prerequisites: r.prerequisites ?? null,
    notes: r.notes ?? null,
    tags: r.tags ?? null,
    relatedApis: r.relatedApis ?? null
  };
}
l.child("tool-registry");
let h = null, v = !1;
const E = /* @__PURE__ */ new Map();
function T(r, e) {
  try {
    return r.postMessage(e), !0;
  } catch (s) {
    const t = s instanceof Error ? s.message : String(s);
    return l.error("port_post_failed", { error: t }), !1;
  }
}
const G = 1e3;
function K(r, e, s) {
  e === "main-thread" || e === "content-script" ? T(s, { type: "relayCancel", id: r, owner: e }) : T(s, { type: "registryCallCancel", id: r });
}
function q(r, e) {
  for (const [s, t] of E)
    clearTimeout(t.timeoutId), K(s, t.owner, t.port), t.settle({
      ok: !1,
      error: { message: e, code: r }
    }), E.delete(s);
}
const _ = /* @__PURE__ */ new Map(), p = /* @__PURE__ */ new Map();
let z = Promise.resolve(), f = null;
function _e(r) {
  l.trace("sessionQueue_enqueue");
  const e = z.then(r);
  return z = e.then(
    () => {
    },
    () => {
    }
  ), e;
}
function Y(r) {
  f && (l.error("runCell_worker_failure", {
    runId: f.runId,
    callId: f.id,
    error: r
  }), self.postMessage({
    type: "error",
    id: f.id,
    error: r,
    runId: f.runId
  }), f = null);
}
self.addEventListener("error", (r) => {
  const e = r.message || (r.error instanceof Error ? r.error.message : "Worker uncaught error");
  l.error("worker_uncaught_error", { error: e }), Y(e);
});
self.addEventListener("unhandledrejection", (r) => {
  const e = r.reason, s = e instanceof Error ? e.message : String(e ?? "Unhandled rejection");
  l.error("worker_unhandled_rejection", { error: s }), Y(s);
});
function c(r, e) {
  _.set(r, e);
}
function be() {
  const r = new Uint8Array(16);
  return crypto.getRandomValues(r), Array.from(r, (e) => e.toString(16).padStart(2, "0")).join("");
}
function we(r) {
  return se(r);
}
const O = /* @__PURE__ */ new Map(), A = /* @__PURE__ */ new Map();
function ke(r, e) {
  var s;
  if (O.has(r))
    throw new Error(`Worker port already registered for owner: ${r}`);
  if (typeof e.addEventListener != "function")
    throw new Error(`Worker port for owner "${r}" cannot receive responses`);
  O.set(r, e), e.addEventListener("message", async (t) => {
    var a;
    const n = t.data;
    if (n !== null && (n.type === "asyncRelayResult" || n.type === "registryCallResult") && typeof n.id == "string") {
      N(n.id, n.result);
      return;
    }
    if (n !== null && n.type === "registryCallCancel" && typeof n.id == "string") {
      (a = A.get(n.id)) == null || a.abort(), A.delete(n.id);
      return;
    }
    if (n !== null && n.type === "registryCall" && typeof n.id == "string" && typeof n.action == "string") {
      const i = n.id, o = new AbortController();
      A.set(i, o);
      const g = _.get(n.action);
      let u;
      if (!g)
        u = {
          ok: !1,
          error: { message: `Unknown worker action: ${n.action}`, code: "E_UNKNOWN" }
        };
      else
        try {
          const d = await g(n.params, {
            action: n.action,
            callId: n.callId,
            runId: n.runId,
            signal: o.signal
          });
          u = o.signal.aborted ? { ok: !1, error: { message: "Relay aborted", code: "E_ABORT" } } : { ok: !0, value: d };
        } catch (d) {
          u = {
            ok: !1,
            error: {
              message: d instanceof Error ? d.message : String(d),
              code: o.signal.aborted ? "E_ABORT" : "E_WORKER_HANDLER"
            }
          };
        }
      A.delete(i), T(e, { type: "registryCallResult", id: i, result: u }) || N(i, {
        ok: !1,
        error: { message: "Failed to deliver worker handler response", code: "E_PORT" }
      });
    }
  }), (s = e.start) == null || s.call(e);
}
function N(r, e) {
  l.trace("resolveAsyncRelayResult", { id: r });
  const s = E.get(r);
  return s ? (s.settle(e), !0) : (l.warn("asyncRelayResult_no_pending_relay", { id: r }), !1);
}
function Me(r) {
  if (r === "main-thread" || r === "content-script")
    return self;
  const e = O.get(r);
  return e || null;
}
function Q(r) {
  const { owner: e, action: s, tabPolicy: t, resolveTimeoutMs: n } = r, a = r.timeoutMs ?? w;
  return (i, o) => {
    l.trace("safePostAsCall_invoke", { owner: e, action: s, callId: o == null ? void 0 : o.callId, runId: o == null ? void 0 : o.runId });
    const g = (n == null ? void 0 : n(i)) ?? a;
    return new Promise((u, d) => {
      var j;
      if ((j = o == null ? void 0 : o.signal) != null && j.aborted) {
        const m = new Error(`Relay aborted for action: ${s}`);
        m.code = "E_ABORT", d(m);
        return;
      }
      const y = Me(e);
      if (!y) {
        d(new Error(`No port available for action: ${s}`));
        return;
      }
      if (E.size >= G) {
        d(new Error(
          `Too many pending calls (${G} limit exceeded). Action: ${s}`
        ));
        return;
      }
      const M = be();
      let W = !1;
      const R = (m) => {
        W || (W = !0, clearTimeout(U), o != null && o.signal && o.signal.removeEventListener("abort", S), E.delete(M), m());
      }, D = () => {
        K(M, e, y);
      }, S = () => {
        D();
        const m = new Error(`Relay aborted for action: ${s}`);
        m.code = "E_ABORT", R(() => d(m));
      };
      o != null && o.signal && o.signal.addEventListener("abort", S);
      const U = setTimeout(() => {
        D(), R(() => d(new Error(`Relay timeout for action: ${s}`)));
      }, g);
      E.set(M, {
        settle: (m) => R(() => u(m)),
        timeoutId: U,
        abort: S,
        owner: e,
        port: y
      });
      const F = o == null ? void 0 : o.runId, B = o == null ? void 0 : o.callId;
      T(y, {
        type: e === "main-thread" || e === "content-script" ? "asyncRelay" : "registryCall",
        id: M,
        owner: e,
        action: s,
        params: i,
        callId: B,
        tabPolicy: t,
        command: { action: s, params: i, runId: F, callId: B },
        runId: F
      }) || R(() => d(new Error(`Failed to post relay for action: ${s}`)));
    });
  };
}
const Re = "worker", w = 3e4, H = 5e3, Ae = 500, Ie = {
  page_goto: "timeout",
  page_wait_for: "timeout",
  tab_wait_for_load: "timeout",
  fetch: "timeout",
  sleep: "duration",
  page_wait: "duration",
  sidepanel_wait: "duration"
}, X = /* @__PURE__ */ new Set(["page_goto"]);
function Te(r, e) {
  if (r === null || typeof r != "object" || Array.isArray(r))
    return null;
  const s = r[e];
  return typeof s == "bigint" ? Number(s) : typeof s == "number" && Number.isFinite(s) ? s : null;
}
function Se(r, e) {
  return X.has(r) ? e * 2 + Ae + H : e + H;
}
function Z(r, e) {
  const s = Ie[r];
  if (!s) return w;
  let t = Te(e, s);
  return t === null && X.has(r) && (t = w), t === null ? w : Math.max(
    w,
    Se(r, t)
  );
}
function Ne(r, e) {
  var a, i;
  r = k(r);
  const s = e == null ? void 0 : e.action;
  if (l.trace("extensionDispatch", { action: s, callId: e == null ? void 0 : e.callId, runId: e == null ? void 0 : e.runId }), !s)
    return Promise.resolve({
      ok: !1,
      error: { message: "Missing action in dispatch context", code: "E_MISSING_ACTION" }
    });
  if (_.has(s)) {
    const o = _.get(s), g = (e == null ? void 0 : e.signal) ?? (e != null && e.runId ? (a = p.get(e.runId)) == null ? void 0 : a.signal : void 0);
    return (async () => {
      try {
        return { ok: !0, value: await o(r, { ...e, signal: g }) };
      } catch (u) {
        const d = u instanceof Error ? u.message : String(u), y = typeof u == "object" && u !== null && "code" in u && typeof u.code == "string" ? u.code : "E_WORKER_HANDLER";
        return { ok: !1, error: { message: d, code: y } };
      }
    })();
  }
  const t = fe(s);
  return t ? Q({
    owner: t.endpoint,
    action: s,
    resolveTimeoutMs: (o) => Z(s, o),
    tabPolicy: t.tabPolicy
  })(r, {
    ...e,
    signal: (e == null ? void 0 : e.signal) ?? (e != null && e.runId ? (i = p.get(e.runId)) == null ? void 0 : i.signal : void 0)
  }) : Promise.resolve({
    ok: !1,
    error: { message: `No route registered for action: ${s}`, code: "E_NO_ROUTE" }
  });
}
function Le(r) {
  if (r.owner === Re) {
    const e = _.get(r.action);
    if (!e)
      throw new Error(
        `No worker-local handler registered for action: ${r.action}`
      );
    return async (s, t) => {
      var a;
      s = k(s);
      const n = (t == null ? void 0 : t.signal) ?? (t != null && t.runId ? (a = p.get(t.runId)) == null ? void 0 : a.signal : void 0);
      try {
        return { ok: !0, value: await e(s, { ...t, action: r.action, signal: n }) };
      } catch (i) {
        const o = i instanceof Error ? i.message : String(i), g = typeof i == "object" && i !== null && "code" in i && typeof i.code == "string" ? i.code : r.errorCode;
        return { ok: !1, error: { message: o, code: g } };
      }
    };
  } else {
    const e = Q({
      owner: r.owner,
      action: r.action,
      resolveTimeoutMs: (s) => Z(r.action, s)
    });
    return (s, t) => {
      var n;
      return e(k(s), {
        ...t,
        signal: (t == null ? void 0 : t.signal) ?? (t != null && t.runId ? (n = p.get(t.runId)) == null ? void 0 : n.signal : void 0)
      });
    };
  }
}
function Ce(r) {
  c("exists", (e) => r.fsExists(e)), c("stat", (e) => r.fsStat(e)), c("read", (e) => r.fsRead(e)), c("readText", (e) => r.fsReadText(e)), c("readBase64", (e) => r.fsReadBase64(e)), c("list", (e) => r.fsList(e)), c("mkdir", (e) => r.fsMkdir(e)), c("delete", (e) => r.fsDelete(e)), c("copy", (e) => r.fsCopy(e)), c("move", (e) => r.fsMove(e)), c("write", (e) => r.fsWrite(e)), c("writeText", (e) => r.fsWriteText(e)), c("writeBase64", (e) => r.fsWriteBase64(e)), c("append", (e) => r.fsAppend(e)), c("appendText", (e) => r.fsAppendText(e)), c("appendBase64", (e) => r.fsAppendBase64(e)), c("readRange", (e) => r.fsReadRange(e)), c("update", (e) => r.fsUpdate(e)), c("hash", (e) => r.fsHash(e));
}
async function ve(r, e) {
  if (v) return;
  await x(), h = new ee(), L(0), oe(L), l.trace("initWasm_start"), Ce(h), he(r);
  const t = r.map((a) => ({
    entry: Ee(a),
    callback: Le(a)
  }));
  try {
    re(t);
  } catch (a) {
    const i = a instanceof Error ? a.message : String(a);
    throw new Error(`Registry registration failed: ${i}`);
  }
  const { freezeManifest: n } = await import("./extension_js.js");
  try {
    n();
  } catch (a) {
    const i = a instanceof Error ? a.message : String(a);
    throw new Error(`Manifest freeze failed: ${i}`);
  }
  if (h.injectRegistryBindings(), e) {
    const a = JSON.stringify(e);
    await h.runCellAsync(
      `(function(){var r=globalThis.chrome&&globalThis.chrome.runtime;if(!r){r={};if(!globalThis.chrome)globalThis.chrome={};globalThis.chrome.runtime=r;}r.id=${a};})();`,
      "",
      "inject-runtime-id"
    );
  }
  v = !0, l.trace("initWasm_done");
}
self.onmessage = async (r) => {
  const e = r.data;
  if (l.trace("onmessage", { type: e.type, id: "id" in e ? e.id : void 0 }), e.type === "asyncRelayResult") {
    l.trace("asyncRelayResult", { id: e.id }), N(e.id, e.result);
    return;
  }
  if (e.type === "registerWorkerPort") {
    const t = r.ports[0];
    if (!t) {
      l.error("register_worker_port_missing", { owner: e.owner });
      return;
    }
    ke(e.owner, t);
    return;
  }
  if (e.type === "init") {
    try {
      await ve(e.manifest, e.extensionId), self.postMessage({ type: "ready" });
    } catch (t) {
      const n = t instanceof Error ? t.message : String(t);
      l.error("worker_init_failed", { error: n }), self.postMessage({ type: "error", error: `WASM init failed: ${n}` });
    }
    return;
  }
  if (e.type === "setLogLevel") {
    L(e.level), ne(we(e.level)), l.trace("set_log_level", { level: e.level });
    return;
  }
  if (!v || !h) {
    self.postMessage({
      type: "error",
      id: e.id,
      error: "WASM not initialized"
    });
    return;
  }
  const s = h;
  await _e(async () => {
    switch (e.type) {
      case "runCell": {
        const t = e.runId, n = new AbortController();
        t && p.set(t, n), f = { id: e.id, runId: t }, l.trace("runCell_start", { runId: t, callId: e.id, codeLen: e.code.length });
        try {
          const a = await s.runCellAsync(
            e.code,
            e.stdin || "",
            t || ""
          );
          l.trace("runCell_done", { runId: t, callId: e.id, status: a.status }), self.postMessage({
            type: "result",
            id: e.id,
            data: a,
            runId: t
          });
        } catch (a) {
          const i = a instanceof Error ? a.message : String(a);
          l.error("runCell_error", { runId: t, error: i }), self.postMessage({
            type: "error",
            id: e.id,
            error: i,
            runId: t
          });
        } finally {
          (f == null ? void 0 : f.id) === e.id && (f = null), t && p.delete(t);
        }
        break;
      }
      case "reset": {
        s.setAborted(!0);
        for (const t of p.values()) t.abort();
        p.clear(), q("E_RESET", "Worker reset");
        try {
          s.reset(), self.postMessage({ type: "result", id: e.id, data: { ok: !0 } });
        } catch (t) {
          const n = t instanceof Error ? t.message : String(t);
          self.postMessage({ type: "error", id: e.id, error: n });
        }
        break;
      }
      case "stop": {
        s.setAborted(!0);
        for (const t of p.values()) t.abort();
        p.clear(), q("E_STOPPED", "Worker stopped"), self.postMessage({ type: "result", id: e.id, data: { ok: !0 } });
        break;
      }
      case "setFuelLimit": {
        try {
          s.set_fuel_limit(e.limit), e.id && self.postMessage({ type: "result", id: e.id, data: { ok: !0 } });
        } catch (t) {
          if (e.id) {
            const n = t instanceof Error ? t.message : String(t);
            self.postMessage({ type: "error", id: e.id, error: n });
          }
        }
        break;
      }
      case "inspectGlobals": {
        try {
          const t = s.inspect_globals();
          self.postMessage({ type: "result", id: e.id, data: t });
        } catch (t) {
          const n = t instanceof Error ? t.message : String(t);
          self.postMessage({ type: "error", id: e.id, error: n });
        }
        break;
      }
      case "apiDocs": {
        try {
          const t = s.apiDocs(e.format);
          self.postMessage({ type: "result", id: e.id, data: t });
        } catch (t) {
          const n = t instanceof Error ? t.message : String(t);
          self.postMessage({ type: "error", id: e.id, error: n });
        }
        break;
      }
      case "loadLibrary": {
        try {
          const t = s.load_library(e.source);
          self.postMessage({ type: "result", id: e.id, data: t });
        } catch (t) {
          const n = t instanceof Error ? t.message : String(t);
          self.postMessage({ type: "error", id: e.id, error: n });
        }
        break;
      }
      case "fsCall": {
        const t = _.get(e.action);
        if (!t) {
          self.postMessage({
            type: "error",
            id: e.id,
            error: `Unknown fs action: ${e.action}`
          });
          break;
        }
        try {
          const n = await t(e.params);
          self.postMessage({ type: "result", id: e.id, data: n });
        } catch (n) {
          const a = n instanceof Error ? n.message : String(n);
          self.postMessage({ type: "error", id: e.id, error: a });
        }
        break;
      }
      default: {
        l.error("unhandled_worker_message", { type: e.type });
        break;
      }
    }
  });
};
export {
  w as DEFAULT_RELAY_TIMEOUT_MS,
  Le as createExecutableCallback,
  Ne as extensionDispatch,
  c as registerWorkerHandler,
  ke as registerWorkerPort,
  N as resolveAsyncRelayResult,
  Z as resolveRelayTimeoutMs,
  Q as safePostAsCall,
  q as settleAllPendingRelays
};
