// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Flags: --expose-wasm

utils.load('test/inspector/wasm-inspector-test.js');

InspectorTest.log("Tests how wasm scripts are reported");

let contextGroup = new InspectorTest.ContextGroup();
let sessions = [
  // Main session.
  trackScripts(),
  // Extra session to verify that all inspectors get same messages.
  // See https://bugs.chromium.org/p/v8/issues/detail?id=9725.
  trackScripts(),
];

// Create module with given custom sections.
function createModule(...customSections) {
  var builder = new WasmModuleBuilder();
  builder.addFunction('nopFunction', kSig_v_v).addBody([kExprNop]);
  builder.addFunction('main', kSig_v_v)
      .addBody([kExprBlock, kWasmStmt, kExprI32Const, 2, kExprDrop, kExprEnd])
      .exportAs('main');
  for (var { name, value } of customSections) {
    builder.addCustomSection(name, value);
  }
  return builder.toArray();
}

function testFunction(bytes) {
  // Compilation triggers registration of wasm scripts.
  new WebAssembly.Module(new Uint8Array(bytes));
}

// Generate stable IDs.
let scriptIds = {};
function nextStableId(id) {
  if (!(id in scriptIds)) {
    scriptIds[id] = Object.keys(scriptIds).length;
  }
  return scriptIds[id];
}

contextGroup.addScript(testFunction.toString(), 0, 0, 'v8://test/testFunction');

InspectorTest.log(
    'Check that each inspector gets a wasm script at module creation time.');

// Sample .debug_info section.
// Content doesn't matter, as we don't try to parse it in V8,
// but should be non-empty to check that we're skipping it correctly.
const embeddedDWARFSection = {
  name: '.debug_info',
  value: [1, 2, 3, 4, 5]
};

// Sample external_debug_info section set to "abc".
const externalDWARFSection = {
  name: 'external_debug_info',
  value: [3, 97, 98, 99]
};

// Sample sourceMappingURL section set to "abc".
const sourceMapSection = {
  name: 'sourceMappingURL',
  value: [3, 97, 98, 99]
};

sessions[0]
    .Protocol.Runtime
    .evaluate({
      'expression': `//# sourceURL=v8://test/runTestRunction

      // no debug info
      testFunction([${createModule()}]);

      // shared script for identical modules
      testFunction([${createModule()}]);

      // External DWARF
      testFunction([${createModule(externalDWARFSection)}]);

      // Embedded DWARF
      testFunction([${createModule(embeddedDWARFSection)}]);

      // Source map
      testFunction([${createModule(sourceMapSection)}]);

      // SourceMap + External DWARF
      testFunction([${createModule(sourceMapSection, externalDWARFSection)}]);

      // External DWARF + SourceMap (different order)
      testFunction([${createModule(externalDWARFSection, sourceMapSection)}]);

      // Embedded DWARF + External DWARF
      testFunction([${
          createModule(embeddedDWARFSection, externalDWARFSection)}]);

      // External + Embedded DWARF (different order)
      testFunction([${
          createModule(externalDWARFSection, embeddedDWARFSection)}]);

      // Embedded DWARF + source map
      testFunction([${createModule(embeddedDWARFSection, sourceMapSection)}]);

      // Source map + Embedded DWARF (different order)
      testFunction([${createModule(sourceMapSection, embeddedDWARFSection)}]);
      `
    })
    .then(
        () => (
            // At this point all scripts were parsed.
            // Stop tracking and wait for script sources in each session.
            Promise.all(sessions.map(session => session.getScripts()))))
    .catch(err => {
      InspectorTest.log(err.stack);
    })
    .then(() => InspectorTest.completeTest());

function trackScripts(debuggerParams) {
  let {id: sessionId, Protocol} = contextGroup.connect();
  let scripts = [];

  Protocol.Debugger.enable(debuggerParams);
  Protocol.Debugger.onScriptParsed(handleScriptParsed);

  async function loadScript({
    url,
    scriptId,
    sourceMapURL,
    startColumn,
    endColumn,
    codeOffset,
    debugSymbols
  }) {
    let stableId = nextStableId(scriptId);
    InspectorTest.log(`Session #${sessionId}: Script #${
        scripts.length} parsed. URL: ${url}. Script ID: ${
        stableId}, Source map URL: ${sourceMapURL}, debug symbols: ${
        debugSymbols.type}:${debugSymbols.externalURL}. module begin: ${
        startColumn}, module end: ${endColumn}, code offset: ${codeOffset}`);
    let {result: {scriptSource, bytecode}} =
        await Protocol.Debugger.getScriptSource({scriptId});
    if (bytecode) {
      if (scriptSource) {
        InspectorTest.log('Unexpected scriptSource with bytecode: ');
        InspectorTest.log(scriptSource);
      }
      // Binary value is represented as base64 in JSON, decode it.
      bytecode = InspectorTest.decodeBase64(bytecode);
      // Check that it can be parsed back to a WebAssembly module.
      let module = new WebAssembly.Module(bytecode);
      scriptSource =
          `
Raw: ${Array.from(bytecode, b => ('0' + b.toString(16)).slice(-2)).join(' ')}
Imports: [${
              WebAssembly.Module.imports(module)
                  .map(i => `${i.name}: ${i.kind} from "${i.module}"`)
                  .join(', ')}]
Exports: [${
              WebAssembly.Module.exports(module)
                  .map(e => `${e.name}: ${e.kind}`)
                  .join(', ')}]
      `.trim();
    }
    InspectorTest.log(`Session #${sessionId}: Source for ${url}:`);
    InspectorTest.log(scriptSource);
  }

  function handleScriptParsed({params}) {
    if (params.url.startsWith('wasm://')) {
      scripts.push(loadScript(params));
    }
  }

  return {
    Protocol,
    getScripts: () => Promise.all(scripts),
  };
}
