// Copyright 2017 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.

let {session, contextGroup, Protocol} = InspectorTest.start('Tests stepping through wasm scripts');

utils.load('test/mjsunit/wasm/wasm-constants.js');
utils.load('test/mjsunit/wasm/wasm-module-builder.js');

var builder = new WasmModuleBuilder();

var func_a_idx =
    builder.addFunction('wasm_A', kSig_v_v).addBody([kExprNop, kExprNop]).index;

// wasm_B calls wasm_A <param0> times.
builder.addFunction('wasm_B', kSig_v_i)
    .addBody([
      // clang-format off
      kExprLoop, kWasmStmt,               // while
        kExprGetLocal, 0,                 // -
        kExprIf, kWasmStmt,               // if <param0> != 0
          kExprGetLocal, 0,               // -
          kExprI32Const, 1,               // -
          kExprI32Sub,                    // -
          kExprSetLocal, 0,               // decrease <param0>
          kExprCallFunction, func_a_idx,  // -
          kExprBr, 1,                     // continue
          kExprEnd,                       // -
        kExprEnd,                         // break
      // clang-format on
    ])
    .exportAs('main');

var module_bytes = builder.toArray();

function instantiate(bytes) {
  var buffer = new ArrayBuffer(bytes.length);
  var view = new Uint8Array(buffer);
  for (var i = 0; i < bytes.length; ++i) {
    view[i] = bytes[i] | 0;
  }

  var module = new WebAssembly.Module(buffer);
  // Set global variable.
  instance = new WebAssembly.Instance(module);
}

var evalWithUrl = (code, url) => Protocol.Runtime.evaluate(
    {'expression': code + '\n//# sourceURL=v8://test/' + url});

Protocol.Debugger.onPaused(handlePaused);
var wasm_B_scriptId;
var step_actions = [
  'stepInto',  // == stepOver, to call instruction
  'stepInto',  // into call to wasm_A
  'stepOver',  // over first nop
  'stepOut',   // out of wasm_A
  'stepOut',   // out of wasm_B, stop on breakpoint again
  'stepOver',  // to call
  'stepOver',  // over call
  'resume',    // to next breakpoint (third iteration)
  'stepInto',  // to call
  'stepInto',  // into wasm_A
  'stepOut',   // out to wasm_B
  // now step 9 times, until we are in wasm_A again.
  'stepInto', 'stepInto', 'stepInto', 'stepInto', 'stepInto', 'stepInto',
  'stepInto', 'stepInto', 'stepInto',
  // 3 more times, back to wasm_B.
  'stepInto', 'stepInto', 'stepInto',
  // then just resume.
  'resume'
];
for (var action of step_actions) {
  InspectorTest.logProtocolCommandCalls('Debugger.' + action)
}
var sources = {};
var urls = {};
var afterTwoSourcesCallback;

Protocol.Debugger.enable()
    .then(() => InspectorTest.log('Installing code an global variable.'))
    .then(
        () => evalWithUrl('var instance;\n' + instantiate.toString(), 'setup'))
    .then(() => InspectorTest.log('Calling instantiate function.'))
    .then(
        () =>
            (evalWithUrl(
                 'instantiate(' + JSON.stringify(module_bytes) + ')',
                 'callInstantiate'),
             0))
    .then(waitForTwoWasmScripts)
    .then(
        () => InspectorTest.log(
            'Setting breakpoint on line 7 (on the setlocal before the call), url ' +
            urls[wasm_B_scriptId]))
    .then(
        () => Protocol.Debugger.setBreakpoint(
            {'location': {'scriptId': wasm_B_scriptId, 'lineNumber': 7}}))
    .then(printFailure)
    .then(msg => InspectorTest.logMessage(msg.result.actualLocation))
    .then(() => evalWithUrl('instance.exports.main(4)', 'runWasm'))
    .then(() => InspectorTest.log('exports.main returned!'))
    .then(() => InspectorTest.log('Finished!'))
    .then(InspectorTest.completeTest);

function printFailure(message) {
  if (!message.result) {
    InspectorTest.logMessage(message);
  }
  return message;
}

function waitForTwoWasmScripts() {
  var num = 0;
  InspectorTest.log('Waiting for two wasm scripts to be parsed.');
  var promise = new Promise(fulfill => gotBothSources = fulfill);
  function waitForMore() {
    if (num == 2) return promise;
    Protocol.Debugger.onceScriptParsed()
        .then(handleNewScript)
        .then(waitForMore);
  }
  function handleNewScript(msg) {
    var url = msg.params.url;
    if (!url.startsWith('wasm://')) {
      InspectorTest.log('Ignoring script with url ' + url);
      return;
    }
    num += 1;
    var scriptId = msg.params.scriptId;
    urls[scriptId] = url;
    InspectorTest.log('Got wasm script: ' + url);
    if (url.substr(-2) == '-1') wasm_B_scriptId = scriptId;
    InspectorTest.log('Requesting source for ' + url + '...');
    Protocol.Debugger.getScriptSource({scriptId: scriptId})
        .then(printFailure)
        .then(msg => sources[scriptId] = msg.result.scriptSource)
        .then(InspectorTest.log)
        .then(() => Object.keys(sources).length == 2 ? gotBothSources() : 0);
  }
  waitForMore();
  return promise;
}

function printPauseLocation(scriptId, lineNr, columnNr) {
  var lines = sources[scriptId].split('\n');
  var line = '<illegal line number>';
  if (lineNr < lines.length) {
    line = lines[lineNr];
    if (columnNr < line.length) {
      line = line.substr(0, columnNr) + '>' + line.substr(columnNr);
    }
  }
  InspectorTest.log(
      'Paused at ' + urls[scriptId] + ':' + lineNr + ':' + columnNr + ': ' +
      line);
}

async function getValueString(value) {
  if (value.type == 'object') {
    var msg = await Protocol.Runtime.callFunctionOn({
      objectId: value.objectId,
      functionDeclaration: 'function () { return JSON.stringify(this); }'
    });
    printFailure(msg);
    return msg.result.result.value + ' (' + value.description + ')';
  }
  return value.value + ' (' + value.type + ')';
}

async function dumpProperties(message) {
  printFailure(message);
  for (var value of message.result.result) {
    var value_str = await getValueString(value.value);
    InspectorTest.log('   ' + value.name + ': ' + value_str);
  }
}

async function dumpScopeChainsOnPause(message) {
  for (var frame of message.params.callFrames) {
    var functionName = frame.functionName || '(anonymous)';
    var lineNumber = frame.location ? frame.location.lineNumber : frame.lineNumber;
    var columnNumber = frame.location ? frame.location.columnNumber : frame.columnNumber;
    InspectorTest.log(`at ${functionName} (${lineNumber}:${columnNumber}):`);
    for (var scope of frame.scopeChain) {
      InspectorTest.logObject(' - scope (' + scope.type + '):');
      if (scope.type == 'global') {
        InspectorTest.logObject('   -- skipped');
      } else {
        var properties = await Protocol.Runtime.getProperties(
            {'objectId': scope.object.objectId});
        await dumpProperties(properties);
      }
    }
  }
}

function handlePaused(msg) {
  var loc = msg.params.callFrames[0].location;
  printPauseLocation(loc.scriptId, loc.lineNumber, loc.columnNumber);
  dumpScopeChainsOnPause(msg)
      .then(Protocol.Debugger[step_actions.shift() || 'resume']);
}
