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

const {session, contextGroup, Protocol} =
    InspectorTest.start('RemoteObject.CustomPreview');

(async function test() {
  contextGroup.addScript(`
    var a = {name: 'a'};
    var b = {name: 'b'};
    var c = {name: 'c'};
    a.formattableBy1 = true;
    b.formattableBy2 = true;
    c.formattableBy1 = true;
    c.formattableBy2 = true;
    var formatter1 = {
      header: (x) => x.formattableBy1 ? ['span', {}, 'Header formatted by 1 ', x.name] : null,
      hasBody: () => true,
      body: (x) => ['span', {}, 'Body formatted by 1 ', x.name, ['object', {object: {}}]]
    };
    var formatter2 = {
      header: (x) => x.formattableBy2 ? ['span', {}, 'Header formatted by 2 ', x.name] : null,
      hasBody: (x) => true,
      body: (x) => ['span', {}, 'Body formatted by 2 ', x.name]
    };
    var configTest = {};
    var formatterWithConfig1 = {
      header: function(x, config) {
        if (x !== configTest || config)
          return null;
        return ['span', {}, 'Formatter with config ', ['object', {'object': x, 'config': {'info': 'additional info'}}]];
      },
      hasBody: (x) => false,
      body: (x) => { throw 'Unreachable'; }
    }
    var formatterWithConfig2 = {
      header: function(x, config) {
        if (x !== configTest || !config)
          return null;
        return ['span', {}, 'Header ', 'info: ', config.info];
      },
      hasBody: (x, config) => config && config.info,
      body: (x, config) => ['span', {}, 'body', 'info: ', config.info]
    }
    this.devtoolsFormatters = [formatter1, formatter2, formatterWithConfig1, formatterWithConfig2];
  `);

  Protocol.Runtime.enable();
  Protocol.Runtime.setCustomObjectFormatterEnabled({enabled: true});

  Protocol.Runtime.onConsoleAPICalled(m => InspectorTest.logMessage(m));
  InspectorTest.log('Dump custom previews..');
  await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'a'}));
  await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'b'}));
  await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'c'}));
  await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'configTest'}));
  InspectorTest.log('Change formatters order and dump again..');
  await Protocol.Runtime.evaluate({
    expression: 'this.devtoolsFormatters = [formatter2, formatter1, formatterWithConfig1, formatterWithConfig2]'
  });
  await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'a'}));
  await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'b'}));
  await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'c'}));
  await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'configTest'}));

  InspectorTest.log('Test Runtime.getProperties');
  const {result:{result:{objectId}}} = await Protocol.Runtime.evaluate({expression: '({a})'});
  const {result:{result}} = await Protocol.Runtime.getProperties({
    objectId, ownProperties: true, generatePreview: true});
  await dumpCustomPreview(result.find(value => value.name === 'a').value);

  InspectorTest.log('Try to break custom preview..');
  await Protocol.Runtime.evaluate({
    expression: `Object.defineProperty(this, 'devtoolsFormatters', {
      get: () => { throw 1; },
      configurable: true
    })`
  });
  Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
  InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());

  await Protocol.Runtime.evaluate({
    expression: `Object.defineProperty(this, 'devtoolsFormatters', {
      get: () => {
        const arr = [1];
        Object.defineProperty(arr, 0, { get: () => { throw 2; }});
        return arr;
      },
      configurable: true
    })`
  });
  Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
  InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());

  await Protocol.Runtime.evaluate({
    expression: `Object.defineProperty(this, 'devtoolsFormatters', {
      get: () => [{get header() { throw 3; }}],
      configurable: true
    })`
  });
  Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
  InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());

  await Protocol.Runtime.evaluate({
    expression: `Object.defineProperty(this, 'devtoolsFormatters', {
      get: () => [{header: () => { throw 4; }}],
      configurable: true
    })`
  });
  Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
  InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());

  InspectorTest.completeTest();
})()

function dumpCustomPreviewForEvaluate(result) {
  return dumpCustomPreview(result.result.result);
}

async function dumpCustomPreview(result) {
  const { objectId, customPreview } = result;
  InspectorTest.logMessage(customPreview);
  if (customPreview.bodyGetterId) {
    const body = await Protocol.Runtime.callFunctionOn({
      objectId,
      functionDeclaration: 'function(bodyGetter) { return bodyGetter.call(this); }',
      arguments: [ { objectId: customPreview.bodyGetterId } ],
      returnByValue: true
    });
    InspectorTest.logMessage(body);
  }
}
