// This is a small "shim" program which is used when wasm32 unit tests are run
// in this repository. This program is intended to be run in node.js and will
// load a wasm module into memory, instantiate it with a set of imports, and
// then run it.
//
// There's a bunch of helper functions defined here in `imports.env`, but note
// that most of them aren't actually needed to execute most programs. Many of
// these are just intended for completeness or debugging. Hopefully over time
// nothing here is needed for completeness.

const fs = require('fs');
const process = require('process');
const buffer = fs.readFileSync(process.argv[2]);

Error.stackTraceLimit = 20;

let m = new WebAssembly.Module(buffer);

let memory = null;

function viewstruct(data, fields) {
  return new Uint32Array(memory.buffer).subarray(data/4, data/4 + fields);
}

function copystr(a, b) {
  let view = new Uint8Array(memory.buffer).subarray(a, a + b);
  return String.fromCharCode.apply(null, view);
}

function syscall_write([fd, ptr, len]) {
  let s = copystr(ptr, len);
  switch (fd) {
    case 1: process.stdout.write(s); break;
    case 2: process.stderr.write(s); break;
  }
}

function syscall_exit([code]) {
  process.exit(code);
}

function syscall_args(params) {
  let [ptr, len] = params;

  // Calculate total required buffer size
  let totalLen = -1;
  for (let i = 2; i < process.argv.length; ++i) {
    totalLen += Buffer.byteLength(process.argv[i]) + 1;
  }
  if (totalLen < 0) { totalLen = 0; }
  params[2] = totalLen;

  // If buffer is large enough, copy data
  if (len >= totalLen) {
    let view = new Uint8Array(memory.buffer);
    for (let i = 2; i < process.argv.length; ++i) {
      let value = process.argv[i];
      Buffer.from(value).copy(view, ptr);
      ptr += Buffer.byteLength(process.argv[i]) + 1;
    }
  }
}

function syscall_getenv(params) {
  let [keyPtr, keyLen, valuePtr, valueLen] = params;

  let key = copystr(keyPtr, keyLen);
  let value = process.env[key];

  if (value == null) {
    params[4] = 0xFFFFFFFF;
  } else {
    let view = new Uint8Array(memory.buffer);
    let totalLen = Buffer.byteLength(value);
    params[4] = totalLen;
    if (valueLen >= totalLen) {
      Buffer.from(value).copy(view, valuePtr);
    }
  }
}

function syscall_time(params) {
  let t = Date.now();
  let secs = Math.floor(t / 1000);
  let millis = t % 1000;
  params[1] = Math.floor(secs / 0x100000000);
  params[2] = secs % 0x100000000;
  params[3] = Math.floor(millis * 1000000);
}

let imports = {};
imports.env = {
  // These are generated by LLVM itself for various intrinsic calls. Hopefully
  // one day this is not necessary and something will automatically do this.
  fmod: function(x, y) { return x % y; },
  exp2: function(x) { return Math.pow(2, x); },
  exp2f: function(x) { return Math.pow(2, x); },
  ldexp: function(x, y) { return x * Math.pow(2, y); },
  ldexpf: function(x, y) { return x * Math.pow(2, y); },
  sin: Math.sin,
  sinf: Math.sin,
  cos: Math.cos,
  cosf: Math.cos,
  log: Math.log,
  log2: Math.log2,
  log10: Math.log10,
  log10f: Math.log10,

  rust_wasm_syscall: function(index, data) {
    switch (index) {
      case 1: syscall_write(viewstruct(data, 3)); return true;
      case 2: syscall_exit(viewstruct(data, 1)); return true;
      case 3: syscall_args(viewstruct(data, 3)); return true;
      case 4: syscall_getenv(viewstruct(data, 5)); return true;
      case 6: syscall_time(viewstruct(data, 4)); return true;
      default:
        console.log("Unsupported syscall: " + index);
        return false;
    }
  }
};

let instance = new WebAssembly.Instance(m, imports);
memory = instance.exports.memory;
try {
  instance.exports.main();
} catch (e) {
  console.error(e);
  process.exit(101);
}
