// Copyright 2026 The IREE Authors
//
// Licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

// Generic test entry point for gtest/gbenchmark wasm binaries under WASI.
//
// The bundler appends this file after inlined companion code and the generated
// createWasmImports() function, so createWasmImports is available in module
// scope. The bundler also defines __IREE_WASM_BINARY with the .wasm filename.
//
// Provides WASI preview1 syscalls via node:wasi, merges companion imports on
// top, instantiates the wasm binary, and propagates the exit code.

import {readFileSync} from 'node:fs';
import {dirname, resolve} from 'node:path';
import {fileURLToPath} from 'node:url';
import {WASI} from 'node:wasi';

const scriptDirectory = dirname(fileURLToPath(import.meta.url));
const wasmPath = resolve(scriptDirectory, __IREE_WASM_BINARY);

// Build preopens for directories the test needs to access. Bazel sets
// TEST_TMPDIR for scratch space and XML_OUTPUT_FILE for gtest XML output.
// Without preopening these, WASI's sandbox blocks stat/open calls and gtest
// crashes during teardown.
const preopens = {};
if (process.env.TEST_TMPDIR) {
  preopens[process.env.TEST_TMPDIR] = process.env.TEST_TMPDIR;
}
if (process.env.XML_OUTPUT_FILE) {
  const xmlDirectory = dirname(process.env.XML_OUTPUT_FILE);
  preopens[xmlDirectory] = xmlDirectory;
}

// WASI provides the C runtime environment: stdio, filesystem, clocks.
const wasi = new WASI({
  version: 'preview1',
  args: [__IREE_WASM_BINARY, ...process.argv.slice(2)],
  env: process.env,
  preopens,
});

// Start with WASI imports and merge companion imports on top.
// createWasmImports is generated by the bundler — it returns an object keyed
// by wasm import module name. For tests with no companions, it returns {}.
const imports = wasi.getImportObject();
const context = {
  memory: null
};
const companionImports = createWasmImports(context);
for (const [moduleName, moduleImports] of Object.entries(companionImports)) {
  if (imports[moduleName]) {
    Object.assign(imports[moduleName], moduleImports);
  } else {
    imports[moduleName] = moduleImports;
  }
}

// Compile and instantiate.
const wasmBytes = readFileSync(wasmPath);
const {instance} = await WebAssembly.instantiate(wasmBytes, imports);

// Wire up exported memory for companions that need it (e.g., reading
// wasm linear memory for ring drain operations).
context.memory = instance.exports.memory;

// WASI.start() calls _start() on the wasm instance. The WASI runtime handles
// proc_exit internally and sets process.exitCode.
try {
  wasi.start(instance);
} catch (error) {
  // WASI proc_exit throws to unwind the wasm call stack. process.exitCode is
  // already set by the WASI runtime. If it was not set, this is a genuine
  // error (not a proc_exit).
  if (!process.exitCode) {
    console.error(error);
    process.exitCode = 1;
  }
}
