let wasm;

{
  const module = new WebAssembly.Module(await import('fs/promises').then(fs => fs.readFile(new URL('../../src/seahash/simd.wasm', import.meta.url))));
  const instance = new WebAssembly.Instance(module);

  wasm = instance.exports;
}

const u16_max = 2 ** 16;
const u64_max = 2n ** 64n;
const { sea, memory } = wasm;

let len = memory.buffer.byteLength;
let u8 = new Uint8Array(memory.buffer);
const encode_utf8 = globalThis.Deno?.core?.encode ?? globalThis.Buffer?.from.bind(globalThis.Buffer) ?? TextEncoder.prototype.encode.bind(new TextEncoder);

function resize(size) {
  memory.grow(Math.ceil((size - len) / u16_max));

  len = memory.buffer.byteLength;
  u8 = new Uint8Array(memory.buffer);
};

export function hash(buf, a = 0n, b = 0n, c = 0n, d = 0n) {
  if ('string' === typeof buf) buf = encode_utf8(buf);
  if (len < (64 + buf.length)) resize(64 + buf.length);

  u8.set(buf, 64);
  const hash = sea(a, b, c, d, buf.length);
  return 0n <= hash ? hash : (hash + u64_max);
};