// META: global=jsshell
// META: script=/wasm/jsapi/wasm-constants.js
// META: script=/wasm/jsapi/wasm-module-builder.js
// META: script=/wasm/jsapi/assertions.js

function assert_exported_function(fn, { name, length }, description) {
  assert_equals(Object.getPrototypeOf(fn), Function.prototype,
                `${description}: prototype`);

  assert_function_name(fn, name, description);
  assert_function_length(fn, length, description);
}

function assert_Instance(instance, expected_exports) {
  assert_equals(Object.getPrototypeOf(instance), WebAssembly.Instance.prototype,
                "prototype");
  assert_true(Object.isExtensible(instance), "extensible");

  assert_equals(instance.exports, instance.exports, "exports should be idempotent");
  const exports = instance.exports;

  assert_equals(Object.getPrototypeOf(exports), null, "exports prototype");
  assert_false(Object.isExtensible(exports), "extensible exports");
  for (const [key, expected] of Object.entries(expected_exports)) {
    const property = Object.getOwnPropertyDescriptor(exports, key);
    assert_equals(typeof property, "object", `${key} should be present`);
    assert_false(property.writable, `${key}: writable`);
    assert_true(property.enumerable, `${key}: enumerable`);
    assert_false(property.configurable, `${key}: configurable`);
    const actual = property.value;
    assert_true(Object.isExtensible(actual), `${key}: extensible`);

    switch (expected.kind) {
    case "function":
      assert_exported_function(actual, expected, `value of ${key}`);
      break;
    case "global":
      assert_equals(Object.getPrototypeOf(actual), WebAssembly.Global.prototype,
                    `value of ${key}: prototype`);
      assert_equals(actual.value, expected.value, `value of ${key}: value`);
      assert_equals(actual.valueOf(), expected.value, `value of ${key}: valueOf()`);
      break;
    case "memory":
      assert_equals(Object.getPrototypeOf(actual), WebAssembly.Memory.prototype,
                    `value of ${key}: prototype`);
      assert_equals(Object.getPrototypeOf(actual.buffer), ArrayBuffer.prototype,
                    `value of ${key}: prototype of buffer`);
      assert_equals(actual.buffer.byteLength, 0x10000 * expected.size, `value of ${key}: size of buffer`);
      const array = new Uint8Array(actual.buffer);
      assert_equals(array[0], 0, `value of ${key}: first element of buffer`);
      assert_equals(array[array.byteLength - 1], 0, `value of ${key}: last element of buffer`);
      break;
    case "table":
      assert_equals(Object.getPrototypeOf(actual), WebAssembly.Table.prototype,
                    `value of ${key}: prototype`);
      assert_equals(actual.length, expected.length, `value of ${key}: length of table`);
      break;
    }
  }
}

let emptyModuleBinary;
setup(() => {
  emptyModuleBinary = new WasmModuleBuilder().toBuffer();
});

test(() => {
  assert_function_name(WebAssembly.Instance, "Instance", "WebAssembly.Instance");
}, "name");

test(() => {
  assert_function_length(WebAssembly.Instance, 1, "WebAssembly.Instance");
}, "length");

test(() => {
  assert_throws(new TypeError(), () => new WebAssembly.Instance());
}, "No arguments");

test(() => {
  const invalidArguments = [
    undefined,
    null,
    true,
    "",
    Symbol(),
    1,
    {},
    WebAssembly.Module,
    WebAssembly.Module.prototype,
  ];
  for (const argument of invalidArguments) {
    assert_throws(new TypeError(), () => new WebAssembly.Instance(argument),
                  `new Instance(${format_value(argument)})`);
  }
}, "Non-Module arguments");

test(() => {
  const module = new WebAssembly.Module(emptyModuleBinary);
  const invalidArguments = [
    null,
    true,
    "",
    Symbol(),
    1,
  ];
  for (const argument of invalidArguments) {
    assert_throws(new TypeError(), () => new WebAssembly.Instance(module, argument),
                  `new Instance(module, ${format_value(argument)})`);
  }
}, "Non-object imports");

test(() => {
  const module = new WebAssembly.Module(emptyModuleBinary);
  assert_throws(new TypeError(), () => WebAssembly.Instance(module));
}, "Calling");

test(() => {
  const module = new WebAssembly.Module(emptyModuleBinary);
  const arguments = [
    [],
    [undefined],
    [{}],
  ];
  for (const value of arguments) {
    const instance = new WebAssembly.Instance(module, ...arguments);
    assert_Instance(instance, {});
  }
}, "Empty module");

test(() => {
  const builder = new WasmModuleBuilder();
  builder.addImportedGlobal("module", "global1", kWasmI32);
  builder.addImportedGlobal("module", "global2", kWasmI32);
  const buffer = builder.toBuffer();
  const module = new WebAssembly.Module(buffer);
  const order = [];
  const imports = {
    get module() {
      order.push("module getter");
      return {
        get global1() {
          order.push("global1 getter");
          return 0;
        },
        get global2() {
          order.push("global2 getter");
          return 0;
        },
      }
    },
  };
  new WebAssembly.Instance(module, imports);
  const expected = [
    "module getter",
    "global1 getter",
    "module getter",
    "global2 getter",
  ];
  assert_array_equals(order, expected);
}, "getter order for imports object");

test(() => {
  const builder = new WasmModuleBuilder();

  builder.addImport("module", "fn", kSig_v_v);
  builder.addImportedGlobal("module", "global", kWasmI32);
  builder.addImportedMemory("module", "memory", 0, 128);
  builder.addImportedTable("module", "table", 0, 128);

  const buffer = builder.toBuffer();
  const module = new WebAssembly.Module(buffer);
  const instance = new WebAssembly.Instance(module, {
    "module": {
      "fn": function() {},
      "global": 0,
      "memory": new WebAssembly.Memory({ "initial": 64, maximum: 128 }),
      "table": new WebAssembly.Table({ "element": "anyfunc", "initial": 64, maximum: 128 }),
    },
    get "module2"() {
      assert_unreached("Should not get modules that are not imported");
    },
  });
  assert_Instance(instance, {});
}, "imports");

test(() => {
  const builder = new WasmModuleBuilder();

  builder
    .addFunction("fn", kSig_v_d)
    .addBody([
        kExprEnd
    ])
    .exportFunc();
  builder
    .addFunction("fn2", kSig_v_v)
    .addBody([
        kExprEnd
    ])
    .exportFunc();

  builder.setFunctionTableLength(1);
  builder.addExportOfKind("table", kExternalTable, 0);

  builder.addGlobal(kWasmI32, true)
    .exportAs("global")
    .init = 7;
  builder.addGlobal(kWasmF64, true)
    .exportAs("global2")
    .init = 1.2;

  builder.addMemory(4, 8, true);

  const buffer = builder.toBuffer()
  const module = new WebAssembly.Module(buffer);

  const instance = new WebAssembly.Instance(module, {});
  const expected = {
    "fn": { "kind": "function", "name": "0", "length": 1 },
    "fn2": { "kind": "function", "name": "1", "length": 0 },
    "table": { "kind": "table", "length": 1 },
    "global": { "kind": "global", "value": 7 },
    "global2": { "kind": "global", "value": 1.2 },
    "memory": { "kind": "memory", "size": 4 },
  };
  assert_Instance(instance, expected);
}, "exports");
