/* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */
/* eslint-disable no-shadow, max-nested-callbacks */

"use strict";

/**
 * Verify if client can receive binary wasm if 'wasmBinarySource' is set.
 */

var gDebuggee;
var gClient;
var gThreadClient;

Services.prefs.setBoolPref("security.allow_eval_with_system_principal", true);

registerCleanupFunction(() => {
  Services.prefs.clearUserPref("security.allow_eval_with_system_principal");
});

function run_test() {
  if (typeof WebAssembly == "undefined") {
    // wasm is not enabled for this platform
    return;
  }

  initTestDebuggerServer();
  gDebuggee = addTestGlobal("test-wasm-source");
  gClient = new DebuggerClient(DebuggerServer.connectPipe());
  gClient.connect().then(function() {
    Assert.ok(gClient.mainRoot.traits.wasmBinarySource);

    attachTestTabAndResume(
      gClient, "test-wasm-source",
      function(response, targetFront, threadClient) {
        gThreadClient = threadClient;
        gThreadClient.reconfigure({
          observeAsmJS: true,
          wasmBinarySource: true,
        }).then(function() {
          test_source();
        });
      });
  });
  do_test_pending();
}

const EXPECTED_CONTENT = String.fromCharCode(
  0, 97, 115, 109, 1, 0, 0, 0, 1, 132, 128, 128, 128, 0, 1, 96, 0, 0, 3, 130,
  128, 128, 128, 0, 1, 0, 6, 129, 128, 128, 128, 0, 0, 7, 133, 128, 128, 128,
  0, 1, 1, 102, 0, 0, 10, 136, 128, 128, 128, 0, 1, 130, 128, 128, 128, 0, 0,
  11);

function test_source() {
  gThreadClient.once("paused", function(packet) {
    gThreadClient.getSources().then(function(response) {
      Assert.ok(!!response);
      Assert.ok(!!response.sources);

      const source = response.sources.filter(function(s) {
        return s.introductionType === "wasm";
      })[0];

      Assert.ok(!!source);

      const sourceFront = gThreadClient.source(source);
      sourceFront.source().then(function(response) {
        Assert.ok(!!response);
        Assert.ok(!!response.contentType);
        Assert.ok(response.contentType.includes("wasm"));

        const sourceContent = response.source;
        Assert.ok(!!sourceContent);
        Assert.equal(typeof sourceContent, "object");
        Assert.ok("binary" in sourceContent);
        Assert.equal(EXPECTED_CONTENT, sourceContent.binary);

        gThreadClient.resume().then(function() {
          finishClient(gClient);
        });
      });
    });
  });

  /* eslint-disable comma-spacing, max-len */
  gDebuggee.eval("(" + function() {
    // WebAssembly bytecode was generated by running:
    // js -e 'print(wasmTextToBinary("(module(func(export \"f\")))"))'
    const m = new WebAssembly.Module(new Uint8Array([
      0,97,115,109,1,0,0,0,1,132,128,128,128,0,1,96,0,0,3,130,128,128,128,0,1,
      0,6,129,128,128,128,0,0,7,133,128,128,128,0,1,1,102,0,0,10,136,128,128,
      128,0,1,130,128,128,128,0,0,11,
    ]));
    const i = new WebAssembly.Instance(m);
    debugger;
    i.exports.f();
  } + ")()");
}
