/**
 * Resolves the `https://esm.sh/...` imports in web_node/js/wallet_crypto.js to the
 * copies already installed in vps_scheduler/node_modules.
 *
 * Why this exists: wallet_crypto.js is shared with the browser node, so it has to
 * import by URL. Node used to allow that behind --experimental-network-imports,
 * but that flag was removed in Node 22, so on newer Node the crypto import fails
 * and takes the snapshot store (and therefore the producer set) down with it.
 *
 * This only rewrites module resolution. It never changes which algorithm runs:
 * @noble/post-quantum is version-matched exactly to the URL, and the hash and
 * BIP-39 entry points are fixed standards whose outputs are byte-identical
 * across the minor versions involved.
 *
 * Registered via cdn_shim_register.mjs:
 *   node --import ./cdn_shim_register.mjs server.js
 */
const PREFIX = "https://esm.sh/";

/** https://esm.sh/@scope/pkg@1.2.3/sub.js -> @scope/pkg/sub.js */
function toBareSpecifier(url) {
  if (typeof url !== "string" || !url.startsWith(PREFIX)) return null;
  const rest = url.slice(PREFIX.length).split("?")[0].split("#")[0];
  if (!rest) return null;
  const parts = rest.split("/").filter(Boolean);
  if (!parts.length) return null;
  // Scoped packages span two path segments (@scope/name).
  const nameLen = parts[0].startsWith("@") ? 2 : 1;
  const nameParts = parts.slice(0, nameLen);
  if (nameParts.length < nameLen) return null;
  const subPath = parts.slice(nameLen).join("/");
  // Strip the pinned version from the package name, not from the subpath.
  const last = nameParts[nameParts.length - 1];
  const at = last.lastIndexOf("@");
  if (at > 0) nameParts[nameParts.length - 1] = last.slice(0, at);
  const pkg = nameParts.join("/");
  return subPath ? `${pkg}/${subPath}` : pkg;
}

export async function resolve(specifier, context, nextResolve) {
  const bare = toBareSpecifier(specifier);
  if (!bare) return nextResolve(specifier, context);

  // Resolve relative to this hook so vps_scheduler/node_modules is always used,
  // regardless of which file did the importing.
  const parentURL = import.meta.url;
  try {
    return await nextResolve(bare, { ...context, parentURL });
  } catch (err) {
    // Packages disagree on whether subpaths carry .js: @noble/hashes exports
    // "./sha3.js" while @noble/post-quantum exports only "./ml-dsa".
    const alt = bare.endsWith(".js") ? bare.slice(0, -3) : `${bare}.js`;
    try {
      return await nextResolve(alt, { ...context, parentURL });
    } catch (_) {
      throw err;
    }
  }
}
