export interface Pcre2EmscriptenModule {
  readonly HEAPU8: Uint8Array;
  readonly UTF8ToString: (pointer: number) => string;
  readonly _malloc: (size: number) => number;
  readonly _free: (pointer: number) => void;
  readonly _regex_pcre2_bridge_abi_version: () => number;
  readonly _regex_pcre2_config_flags: () => number;
  readonly _regex_pcre2_version: () => number;
  readonly _regex_pcre2_self_test: () => number;
  readonly _regex_pcre2_error_message: (
    errorCode: number,
    outputPointer: number,
    outputCapacity: number,
  ) => number;
  readonly _regex_pcre2_execute: (
    patternPointer: number,
    patternLength: number,
    subjectPointer: number,
    subjectLength: number,
    applicationFlags: number,
    limitsPointer: number,
    recordsPointer: number,
    recordCapacity: number,
    namesPointer: number,
    nameCapacity: number,
    nameBytesPointer: number,
    nameBytesCapacity: number,
    resultPointer: number,
  ) => number;
  readonly _regex_pcre2_substitute: (
    patternPointer: number,
    patternLength: number,
    subjectPointer: number,
    subjectLength: number,
    replacementPointer: number,
    replacementLength: number,
    applicationFlags: number,
    limitsPointer: number,
    recordsPointer: number,
    recordCapacity: number,
    namesPointer: number,
    nameCapacity: number,
    nameBytesPointer: number,
    nameBytesCapacity: number,
    outputPointer: number,
    outputCapacity: number,
    resultPointer: number,
  ) => number;
  readonly _regex_pcre2_trace: (
    patternPointer: number,
    patternLength: number,
    subjectPointer: number,
    subjectLength: number,
    applicationFlags: number,
    limitsPointer: number,
    eventsPointer: number,
    eventCapacity: number,
    markBytesPointer: number,
    markBytesCapacity: number,
    resultPointer: number,
  ) => number;
}

export type Pcre2ModuleFactory = (options: {
  readonly locateFile: (name: string) => string;
  readonly print: (line: string) => void;
  readonly printErr: (line: string) => void;
}) => Promise<Pcre2EmscriptenModule>;

export async function importPcre2ModuleFactory(
  moduleUrl: URL,
): Promise<Pcre2ModuleFactory> {
  const imported = (await import(
    /* @vite-ignore */ moduleUrl.href
  )) as Partial<{ default: Pcre2ModuleFactory }>;
  if (typeof imported.default !== "function") {
    throw new Error("The bundled PCRE2 module has no Emscripten factory.");
  }
  return imported.default;
}
