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

InspectorTest.log('Tests external stack traces');

let contextGroup1 = new InspectorTest.ContextGroup();
let session1 = contextGroup1.connect();
let Protocol1 = session1.Protocol;
let contextGroup2 = new InspectorTest.ContextGroup();
let session2 = contextGroup2.connect();
let Protocol2 = session2.Protocol;

let utilsScript = `
function store(description) {
  let buffer = inspector.storeCurrentStackTrace(description);
  return '[' + new Int32Array(buffer).join(',') + ']';
}

function started(id) {
  inspector.externalAsyncTaskStarted(Int32Array.from(JSON.parse(id)).buffer);
}

function finished(id) {
  inspector.externalAsyncTaskFinished(Int32Array.from(JSON.parse(id)).buffer);
}
//# sourceURL=utils.js`;

contextGroup1.addScript(utilsScript);
contextGroup2.addScript(utilsScript);

InspectorTest.runAsyncTestSuite([
  async function testDebuggerId() {
    InspectorTest.log('Enabling debugger first time..');
    let {result: {debuggerId}} = await Protocol1.Debugger.enable();
    let firstDebuggerId = debuggerId;
    InspectorTest.log('Enabling debugger again..');
    ({result: {debuggerId}} = await Protocol1.Debugger.enable());
    if (firstDebuggerId !== debuggerId) {
      InspectorTest.log(
          'FAIL: second Debugger.enable returns different debugger id');
    } else {
      InspectorTest.log(
          '> second Debugger.enable returns the same debugger id');
    }
    InspectorTest.log('Enabling debugger in another context group..');
    ({result: {debuggerId}} = await Protocol2.Debugger.enable());
    if (firstDebuggerId === debuggerId) {
      InspectorTest.log(
          'FAIL: Debugger.enable in another context group returns the same debugger id');
    } else {
      InspectorTest.log(
          '> Debugger.enable in another context group returns own debugger id');
    }
  },

  async function testInstrumentation() {
    Protocol1.Debugger.enable();
    Protocol1.Debugger.setAsyncCallStackDepth({maxDepth: 32});
    let result = await Protocol1.Runtime.evaluate(
        {expression: 'id = inspector.storeCurrentStackTrace(\'stack\')'});
    let stackTraceId = result.result.result.objectId;
    Protocol1.Runtime.evaluate({
      expression: `inspector.externalAsyncTaskStarted(id);
      debugger;
      inspector.externalAsyncTaskFinished(id);`
    });
    let {params: {callFrames, asyncStackTraceId}} =
        await Protocol1.Debugger.oncePaused();
    result = await Protocol1.Debugger.getStackTrace(
        {stackTraceId: asyncStackTraceId});
    InspectorTest.logMessage(result);
    await Protocol1.Debugger.disable();
  },

  async function testDisableStacksAfterStored() {
    Protocol1.Debugger.enable();
    Protocol1.Debugger.setAsyncCallStackDepth({maxDepth: 32});
    let result = await Protocol1.Runtime.evaluate(
        {expression: 'id = inspector.storeCurrentStackTrace(\'stack\')'});
    let stackTraceId = result.result.result.objectId;
    Protocol1.Debugger.setAsyncCallStackDepth({maxDepth: 0});
    Protocol1.Runtime.evaluate({
      expression: `inspector.externalAsyncTaskStarted(id);
      debugger;
      inspector.externalAsyncTaskFinished(id);`
    });
    let {params: {callFrames, asyncStackTraceId}} =
        await Protocol1.Debugger.oncePaused();
    if (!asyncStackTraceId) {
      InspectorTest.log('> external async stack trace is empty');
    } else {
      InspectorTest.log('FAIL: external async stack trace is reported');
    }
    await Protocol1.Debugger.disable();
  },

  async function testDisableStacksAfterStarted() {
    Protocol1.Debugger.enable();
    Protocol1.Debugger.setAsyncCallStackDepth({maxDepth: 32});
    let result = await Protocol1.Runtime.evaluate(
        {expression: 'id = inspector.storeCurrentStackTrace(\'stack\')'});
    let stackTraceId = result.result.result.objectId;
    Protocol1.Runtime.evaluate(
        {expression: 'inspector.externalAsyncTaskStarted(id);'});
    Protocol1.Debugger.setAsyncCallStackDepth({maxDepth: 0});
    Protocol1.Runtime.evaluate({
      expression: `debugger;
      inspector.externalAsyncTaskFinished(id);`
    });
    let {params: {callFrames, asyncStackTraceId}} =
        await Protocol1.Debugger.oncePaused();
    if (!asyncStackTraceId) {
      InspectorTest.log('> external async stack trace is empty');
    } else {
      InspectorTest.log('FAIL: external async stack trace is reported');
    }
    await Protocol1.Debugger.disable();
  },

  async function testExternalStacks() {
    let debuggerId1 = (await Protocol1.Debugger.enable()).result.debuggerId;
    let debuggerId2 = (await Protocol2.Debugger.enable()).result.debuggerId;
    Protocol1.Debugger.setAsyncCallStackDepth({maxDepth: 32});
    Protocol2.Debugger.setAsyncCallStackDepth({maxDepth: 32});
    let stackTraceId1 = (await Protocol1.Runtime.evaluate({
                          expression: 'store(\'stack\')//# sourceURL=expr1-1.js'
                        })).result.result.value;
    let stackTraceId2 = (await Protocol2.Runtime.evaluate({
                          expression: `started('${stackTraceId1}');
      id = store('stack2');
      finished('${stackTraceId1}');
      id
      //# sourceURL=expr2.js`
                        })).result.result.value;
    Protocol1.Runtime.evaluate({
      expression: `started('${stackTraceId2}');
      debugger;
      finished('${stackTraceId2}');
      id
      //# sourceURL=expr1-2.js`
    });

    let {params: {callFrames, asyncStackTraceId}} =
        await Protocol1.Debugger.oncePaused();
    let debuggers = new Map(
        [[debuggerId1, Protocol1.Debugger], [debuggerId2, Protocol2.Debugger]]);
    let sessions = new Map([[debuggerId1, session1], [debuggerId2, session2]]);
    let currentDebuggerId = debuggerId1;
    while (true) {
      sessions.get(currentDebuggerId).logCallFrames(callFrames);
      if (asyncStackTraceId) {
        currentDebuggerId = asyncStackTraceId.debuggerId;
        let {result: {stackTrace}} =
            await debuggers.get(currentDebuggerId).getStackTrace({
              stackTraceId: asyncStackTraceId
            });
        InspectorTest.log(`-- ${stackTrace.description} --`);
        callFrames = stackTrace.callFrames;
        asyncStackTraceId = stackTrace.parentId;
      } else {
        break;
      }
    }

    Protocol1.Debugger.disable();
    await Protocol2.Debugger.disable();
  }
]);
