// Copyright 2017 The Chromium Authors. All
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * @fileoverview using private properties isn't a Closure violation in tests.
 * @suppress {accessControls}
 */

HeapProfilerTestRunner.createHeapSnapshotMockFactories = function() {
  HeapProfilerTestRunner.createJSHeapSnapshotMockObject = function() {
    return {
      _rootNodeIndex: 0,
      _nodeTypeOffset: 0,
      _nodeNameOffset: 1,
      _nodeEdgeCountOffset: 2,
      _nodeFieldCount: 3,
      _edgeFieldsCount: 3,
      _edgeTypeOffset: 0,
      _edgeNameOffset: 1,
      _edgeToNodeOffset: 2,
      _nodeTypes: ['hidden', 'object'],
      _edgeTypes: ['element', 'property', 'shortcut'],
      _edgeShortcutType: -1,
      _edgeHiddenType: -1,
      _edgeElementType: 0,
      _realNodesLength: 18,
      nodes: new Uint32Array([0, 0, 2, 1, 1, 2, 1, 2, 2, 1, 3, 1, 1, 4, 0, 1, 5, 0]),
      containmentEdges: new Uint32Array([2, 6, 3, 1, 7, 6, 0, 1, 6, 1, 8, 9, 1, 9, 9, 1, 10, 12, 1, 11, 15]),
      strings: ['', 'A', 'B', 'C', 'D', 'E', 'a', 'b', 'ac', 'bc', 'bd', 'ce'],
      _firstEdgeIndexes: new Uint32Array([0, 6, 12, 18, 21, 21, 21]),
      createNode: HeapSnapshotWorker.JSHeapSnapshot.prototype.createNode,
      createEdge: HeapSnapshotWorker.JSHeapSnapshot.prototype.createEdge,
      createRetainingEdge: HeapSnapshotWorker.JSHeapSnapshot.prototype.createRetainingEdge
    };
  };

  HeapProfilerTestRunner.createHeapSnapshotMockRaw = function() {
    return {
      snapshot: {
        meta: {
          node_fields: ['type', 'name', 'id', 'self_size', 'retained_size', 'dominator', 'edge_count'],
          node_types: [['hidden', 'object'], '', '', '', '', '', ''],
          edge_fields: ['type', 'name_or_index', 'to_node'],
          edge_types: [['element', 'property', 'shortcut'], '', '']
        },

        node_count: 6,
        edge_count: 7
      },

      nodes: [
        0, 0, 1, 0, 20, 0, 2, 1, 1, 2, 2, 2, 0,  2, 1, 2, 3, 3, 8, 0,  2,
        1, 3, 4, 4, 10, 0, 1, 1, 4, 5, 5, 5, 14, 0, 1, 5, 6, 6, 6, 21, 0
      ],

      edges: [1, 6, 7, 1, 7, 14, 0, 1, 14, 1, 8, 21, 1, 9, 21, 1, 10, 28, 1, 11, 35],
      strings: ['', 'A', 'B', 'C', 'D', 'E', 'a', 'b', 'ac', 'bc', 'bd', 'ce']
    };
  };

  HeapProfilerTestRunner._postprocessHeapSnapshotMock = function(mock) {
    mock.nodes = new Uint32Array(mock.nodes);
    mock.edges = new Uint32Array(mock.edges);
    return mock;
  };

  HeapProfilerTestRunner.createHeapSnapshotMock = function() {
    return HeapProfilerTestRunner._postprocessHeapSnapshotMock(HeapProfilerTestRunner.createHeapSnapshotMockRaw());
  };

  HeapProfilerTestRunner.createHeapSnapshotMockWithDOM = function() {
    return HeapProfilerTestRunner._postprocessHeapSnapshotMock({
      snapshot: {
        meta: {
          node_fields: ['type', 'name', 'id', 'edge_count'],
          node_types: [['hidden', 'object', 'synthetic'], '', '', ''],
          edge_fields: ['type', 'name_or_index', 'to_node'],
          edge_types: [['element', 'hidden', 'internal'], '', '']
        },

        node_count: 13,
        edge_count: 13
      },

      nodes: [
        2, 0, 1, 4, 1, 11, 2, 2, 1, 11, 3, 3, 2,  5, 4, 0, 2,  6, 5, 1,  1,  1, 6, 0, 1,  2,
        7, 1, 1, 4, 8, 2,  1, 8, 9, 0,  1, 7, 10, 0, 1, 3, 11, 0, 1, 10, 12, 0, 1, 9, 13, 0
      ],

      edges: [
        0,  1, 4, 0,  2, 8, 0,  3, 12, 0,  4, 16, 0,  1, 20, 0,  2, 24, 0, 1,
        24, 0, 2, 28, 1, 3, 32, 0, 1,  36, 0, 1,  40, 2, 12, 44, 2, 1,  48
      ],

      strings: ['', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'M', 'N', 'Window', 'native']
    });
  };

  HeapProfilerTestRunner.HeapNode = function(name, selfSize, type, id) {
    this._type = type || HeapProfilerTestRunner.HeapNode.Type.object;
    this._name = name;
    this._selfSize = selfSize || 0;
    this._builder = null;
    this._edges = {};
    this._edgesCount = 0;
    this._id = id;
  };

  HeapProfilerTestRunner.HeapNode.Type = {
    'hidden': 'hidden',
    'array': 'array',
    'string': 'string',
    'object': 'object',
    'code': 'code',
    'closure': 'closure',
    'regexp': 'regexp',
    'number': 'number',
    'native': 'native',
    'synthetic': 'synthetic',
    'bigint': 'bigint'
  };

  HeapProfilerTestRunner.HeapNode.prototype = {
    linkNode: function(node, type, nameOrIndex) {
      if (!this._builder)
        throw new Error('parent node is not connected to a snapshot');

      if (!node._builder)
        node._setBuilder(this._builder);

      if (nameOrIndex === undefined)
        nameOrIndex = this._edgesCount;

      ++this._edgesCount;

      if (nameOrIndex in this._edges) {
        throw new Error(
            'Can\'t add edge with the same nameOrIndex. nameOrIndex: ' + nameOrIndex +
            ' oldNodeName: ' + this._edges[nameOrIndex]._name + ' newNodeName: ' + node._name);
      }

      this._edges[nameOrIndex] = new HeapProfilerTestRunner.HeapEdge(node, type, nameOrIndex);
    },

    _setBuilder: function(builder) {
      if (this._builder)
        throw new Error('node reusing is prohibited');

      this._builder = builder;
      this._ordinal = this._builder._registerNode(this);
    },

    _serialize: function(rawSnapshot) {
      rawSnapshot.nodes.push(this._builder.lookupNodeType(this._type));
      rawSnapshot.nodes.push(this._builder.lookupOrAddString(this._name));
      rawSnapshot.nodes.push(this._id || this._ordinal * 2 + 1);
      rawSnapshot.nodes.push(this._selfSize);
      rawSnapshot.nodes.push(0);
      rawSnapshot.nodes.push(0);
      rawSnapshot.nodes.push(Object.keys(this._edges).length);

      for (const i in this._edges)
        this._edges[i]._serialize(rawSnapshot);
    }
  };

  HeapProfilerTestRunner.HeapEdge = function(targetNode, type, nameOrIndex) {
    this._targetNode = targetNode;
    this._type = type;
    this._nameOrIndex = nameOrIndex;
  };

  HeapProfilerTestRunner.HeapEdge.prototype = {
    _serialize: function(rawSnapshot) {
      if (!this._targetNode._builder)
        throw new Error('Inconsistent state of node: ' + this._name + ' no builder assigned');

      const builder = this._targetNode._builder;
      rawSnapshot.edges.push(builder.lookupEdgeType(this._type));
      rawSnapshot.edges.push(
          (typeof this._nameOrIndex === 'string' ? builder.lookupOrAddString(this._nameOrIndex) : this._nameOrIndex));
      rawSnapshot.edges.push(this._targetNode._ordinal * builder.nodeFieldsCount);
    }
  };

  HeapProfilerTestRunner.HeapEdge.Type = {
    'context': 'context',
    'element': 'element',
    'property': 'property',
    'internal': 'internal',
    'hidden': 'hidden',
    'shortcut': 'shortcut',
    'weak': 'weak'
  };

  HeapProfilerTestRunner.HeapSnapshotBuilder = function() {
    this._nodes = [];
    this._string2id = {};
    this._strings = [];
    this.nodeFieldsCount = 7;
    this._nodeTypesMap = {};
    this._nodeTypesArray = [];

    for (const nodeType in HeapProfilerTestRunner.HeapNode.Type) {
      this._nodeTypesMap[nodeType] = this._nodeTypesArray.length;
      this._nodeTypesArray.push(nodeType);
    }

    this._edgeTypesMap = {};
    this._edgeTypesArray = [];

    for (const edgeType in HeapProfilerTestRunner.HeapEdge.Type) {
      this._edgeTypesMap[edgeType] = this._edgeTypesArray.length;
      this._edgeTypesArray.push(edgeType);
    }

    this.rootNode = new HeapProfilerTestRunner.HeapNode('root', 0, 'object');
    this.rootNode._setBuilder(this);
  };

  HeapProfilerTestRunner.HeapSnapshotBuilder.prototype = {
    generateSnapshot: function() {
      const rawSnapshot = {
        'snapshot': {
          'meta': {
            'node_fields': ['type', 'name', 'id', 'self_size', 'retained_size', 'dominator', 'edge_count'],
            'node_types': [this._nodeTypesArray, 'string', 'number', 'number', 'number', 'number', 'number'],
            'edge_fields': ['type', 'name_or_index', 'to_node'],
            'edge_types': [this._edgeTypesArray, 'string_or_number', 'node']
          }
        },

        'nodes': [],
        'edges': [],
        'strings': []
      };

      for (let i = 0; i < this._nodes.length; ++i)
        this._nodes[i]._serialize(rawSnapshot);

      rawSnapshot.strings = this._strings.slice();
      const meta = rawSnapshot.snapshot.meta;
      rawSnapshot.snapshot.edge_count = rawSnapshot.edges.length / meta.edge_fields.length;
      rawSnapshot.snapshot.node_count = rawSnapshot.nodes.length / meta.node_fields.length;
      return rawSnapshot;
    },

    createJSHeapSnapshot: function() {
      const parsedSnapshot = HeapProfilerTestRunner._postprocessHeapSnapshotMock(this.generateSnapshot());
      return new HeapSnapshotWorker.JSHeapSnapshot(parsedSnapshot, new HeapSnapshotWorker.HeapSnapshotProgress());
    },

    _registerNode: function(node) {
      this._nodes.push(node);
      return this._nodes.length - 1;
    },

    lookupNodeType: function(typeName) {
      if (typeName === undefined)
        throw new Error('wrong node type: ' + typeName);

      if (!(typeName in this._nodeTypesMap))
        throw new Error('wrong node type name: ' + typeName);

      return this._nodeTypesMap[typeName];
    },

    lookupEdgeType: function(typeName) {
      if (!(typeName in this._edgeTypesMap))
        throw new Error('wrong edge type name: ' + typeName);

      return this._edgeTypesMap[typeName];
    },

    lookupOrAddString: function(string) {
      if (string in this._string2id)
        return this._string2id[string];

      this._string2id[string] = this._strings.length;
      this._strings.push(string);
      return this._strings.length - 1;
    }
  };

  HeapProfilerTestRunner.createHeapSnapshot = function(instanceCount, firstId) {
    let seed = 881669;

    function pseudoRandom(limit) {
      seed = seed * 355109 + 153763 >> 2 & 65535;
      return seed % limit;
    }

    const builder = new HeapProfilerTestRunner.HeapSnapshotBuilder();
    const rootNode = builder.rootNode;
    const gcRootsNode =
        new HeapProfilerTestRunner.HeapNode('(GC roots)', 0, HeapProfilerTestRunner.HeapNode.Type.synthetic);
    rootNode.linkNode(gcRootsNode, HeapProfilerTestRunner.HeapEdge.Type.element);
    const windowNode = new HeapProfilerTestRunner.HeapNode('Window', 20);
    rootNode.linkNode(windowNode, HeapProfilerTestRunner.HeapEdge.Type.shortcut);
    gcRootsNode.linkNode(windowNode, HeapProfilerTestRunner.HeapEdge.Type.element);

    for (let i = 0; i < instanceCount; ++i) {
      const sizeOfB = pseudoRandom(20) + 1;
      const nodeB = new HeapProfilerTestRunner.HeapNode('B', sizeOfB, undefined, firstId++);
      windowNode.linkNode(nodeB, HeapProfilerTestRunner.HeapEdge.Type.element);
      const sizeOfA = pseudoRandom(50) + 1;
      const nodeA = new HeapProfilerTestRunner.HeapNode('A', sizeOfA, undefined, firstId++);
      nodeB.linkNode(nodeA, HeapProfilerTestRunner.HeapEdge.Type.property, 'a');
      nodeA.linkNode(nodeA, HeapProfilerTestRunner.HeapEdge.Type.property, 'a');
    }

    return builder.generateSnapshot();
  };
};

HeapProfilerTestRunner.createHeapSnapshotMockFactories();

HeapProfilerTestRunner.startProfilerTest = function(callback) {
  TestRunner.addResult('Profiler was enabled.');
  HeapProfilerTestRunner._panelReset = TestRunner.override(UI.panels.heap_profiler, '_reset', function() {}, true);
  TestRunner.addSniffer(UI.panels.heap_profiler, '_addProfileHeader', HeapProfilerTestRunner._profileHeaderAdded, true);
  TestRunner.addSniffer(Profiler.ProfileView.prototype, 'refresh', HeapProfilerTestRunner._profileViewRefresh, true);
  TestRunner.addSniffer(Profiler.HeapSnapshotView.prototype, 'show', HeapProfilerTestRunner._snapshotViewShown, true);

  Profiler.HeapSnapshotContainmentDataGrid.prototype.defaultPopulateCount = function() {
    return 10;
  };

  Profiler.HeapSnapshotConstructorsDataGrid.prototype.defaultPopulateCount = function() {
    return 10;
  };

  Profiler.HeapSnapshotDiffDataGrid.prototype.defaultPopulateCount = function() {
    return 5;
  };

  TestRunner.addResult('Detailed heap profiles were enabled.');
  TestRunner.safeWrap(callback)();
};

HeapProfilerTestRunner.completeProfilerTest = function() {
  TestRunner.addResult('');
  TestRunner.addResult('Profiler was disabled.');
  TestRunner.completeTest();
};

HeapProfilerTestRunner.runHeapSnapshotTestSuite = function(testSuite) {
  const testSuiteTests = testSuite.slice();
  let completeTestStack;

  function runner() {
    if (!testSuiteTests.length) {
      if (completeTestStack)
        TestRunner.addResult('FAIL: test already completed at ' + completeTestStack);

      HeapProfilerTestRunner.completeProfilerTest();
      completeTestStack = new Error().stack;
      return;
    }

    const nextTest = testSuiteTests.shift();
    TestRunner.addResult('');
    TestRunner.addResult(
        'Running: ' +
        /function\s([^(]*)/.exec(nextTest)[1]);
    HeapProfilerTestRunner._panelReset.call(UI.panels.heap_profiler);
    TestRunner.safeWrap(nextTest)(runner, runner);
  }

  HeapProfilerTestRunner.startProfilerTest(runner);
};

HeapProfilerTestRunner.assertColumnContentsEqual = function(reference, actual) {
  const length = Math.min(reference.length, actual.length);

  for (let i = 0; i < length; ++i)
    TestRunner.assertEquals(reference[i], actual[i], 'row ' + i);

  if (reference.length > length)
    TestRunner.addResult('extra rows in reference array:\n' + reference.slice(length).join('\n'));
  else if (actual.length > length)
    TestRunner.addResult('extra rows in actual array:\n' + actual.slice(length).join('\n'));
};

HeapProfilerTestRunner.checkArrayIsSorted = function(contents, sortType, sortOrder) {
  function simpleComparator(a, b) {
    return (a < b ? -1 : (a > b ? 1 : 0));
  }

  function parseSize(size) {
    return parseInt(size.replace(/[\xa0,]/g, ''), 10);
  }

  const extractor = {
    text: function(data) {
      data;
    },

    number: function(data) {
      return parseInt(data, 10);
    },

    size: parseSize,

    name: function(data) {
      return data;
    },

    id: function(data) {
      return parseInt(data, 10);
    }
  }[sortType];

  if (!extractor) {
    TestRunner.addResult('Invalid sort type: ' + sortType);
    return;
  }

  let acceptableComparisonResult;

  if (sortOrder === DataGrid.DataGrid.Order.Ascending) {
    acceptableComparisonResult = -1;
  } else if (sortOrder === DataGrid.DataGrid.Order.Descending) {
    acceptableComparisonResult = 1;
  } else {
    TestRunner.addResult('Invalid sort order: ' + sortOrder);
    return;
  }

  for (let i = 0; i < contents.length - 1; ++i) {
    const a = extractor(contents[i]);
    const b = extractor(contents[i + 1]);
    const result = simpleComparator(a, b);

    if (result !== 0 && result !== acceptableComparisonResult) {
      TestRunner.addResult(
          'Elements ' + i + ' and ' + (i + 1) + ' are out of order: ' + a + ' ' + b + ' (' + sortOrder + ')');
    }
  }
};

HeapProfilerTestRunner.clickColumn = function(column, callback) {
  callback = TestRunner.safeWrap(callback);
  const cell = this._currentGrid()._headerTableHeaders[column.id];

  const event = {
    target: {
      enclosingNodeOrSelfWithNodeName: function() {
        return cell;
      }
    }
  };

  function sortingComplete() {
    HeapProfilerTestRunner._currentGrid().removeEventListener(
        Profiler.HeapSnapshotSortableDataGrid.Events.SortingComplete, sortingComplete, this);
    TestRunner.assertEquals(column.id, this._currentGrid().sortColumnId(), 'unexpected sorting');
    column.sort = this._currentGrid().sortOrder();

    function callCallback() {
      callback(column);
    }

    setTimeout(callCallback, 0);
  }

  HeapProfilerTestRunner._currentGrid().addEventListener(
      Profiler.HeapSnapshotSortableDataGrid.Events.SortingComplete, sortingComplete, this);
  this._currentGrid()._clickInHeaderCell(event);
};

HeapProfilerTestRunner.clickRowAndGetRetainers = function(row, callback) {
  callback = TestRunner.safeWrap(callback);

  const event = {
    target: {
      enclosingNodeOrSelfWithNodeName: function() {
        return row._element;
      },

      selectedNode: row
    }
  };

  this._currentGrid()._mouseDownInDataTable(event);
  const rootNode = HeapProfilerTestRunner.currentProfileView()._retainmentDataGrid.rootNode();
  rootNode.once(Profiler.HeapSnapshotGridNode.Events.PopulateComplete).then(() => callback(rootNode));
};

HeapProfilerTestRunner.clickShowMoreButton = function(buttonName, row, callback) {
  callback = TestRunner.safeWrap(callback);
  const parent = row.parent;
  parent.once(Profiler.HeapSnapshotGridNode.Events.PopulateComplete).then(() => setTimeout(() => callback(parent), 0));
  row[buttonName].click();
};

HeapProfilerTestRunner.columnContents = function(column, row) {
  this._currentGrid().updateVisibleNodes();
  const columnOrdinal = HeapProfilerTestRunner.viewColumns().indexOf(column);
  const result = [];
  const parent = row || this._currentGrid().rootNode();

  for (let node = parent.children[0]; node; node = node.traverseNextNode(true, parent, true)) {
    if (!node.selectable)
      continue;

    let content = node.element().children[columnOrdinal];

    if (content.firstElementChild)
      content = content.firstElementChild;

    result.push(content.textContent);
  }

  return result;
};

HeapProfilerTestRunner.countDataRows = function(row, filter) {
  let result = 0;

  filter = filter || function(node) {
    return node.selectable;
  };

  for (let node = row.children[0]; node; node = node.traverseNextNode(true, row, true)) {
    if (filter(node))
      ++result;
  }

  return result;
};

HeapProfilerTestRunner.expandRow = function(row, callback) {
  callback = TestRunner.safeWrap(callback);
  row.once(Profiler.HeapSnapshotGridNode.Events.PopulateComplete).then(() => setTimeout(() => callback(row), 0));

  (function expand() {
    if (row.hasChildren())
      row.expand();
    else
      setTimeout(expand, 0);
  })();
};

HeapProfilerTestRunner.expandRowPromise = function(row) {
  return new Promise(resolve => HeapProfilerTestRunner.expandRow(row, resolve));
};

HeapProfilerTestRunner.findAndExpandGCRoots = function(callback) {
  HeapProfilerTestRunner.findAndExpandRow('(GC roots)', callback);
};

HeapProfilerTestRunner.findAndExpandWindow = function(callback) {
  HeapProfilerTestRunner.findAndExpandRow('Window', callback);
};

HeapProfilerTestRunner.findAndExpandRow = async function(name, callback) {
  const row = HeapProfilerTestRunner.findRow(name);
  TestRunner.assertEquals(true, !!row, `"${name}" row`);
  await HeapProfilerTestRunner.expandRowPromise(row);
  TestRunner.safeWrap(callback)(row);
  return row;
};

HeapProfilerTestRunner.findButtonsNode = function(row, startNode) {
  for (let node = startNode || row.children[0]; node; node = node.traverseNextNode(true, row, true)) {
    if (!node.selectable && node.showNext)
      return node;
  }
  return null;
};

HeapProfilerTestRunner.findRow = function(name, parent) {
  return HeapProfilerTestRunner.findMatchingRow(node => node._name === name, parent);
};

HeapProfilerTestRunner.findMatchingRow = function(matcher, parent) {
  parent = parent || this._currentGrid().rootNode();

  for (let node = parent.children[0]; node; node = node.traverseNextNode(true, parent, true)) {
    if (matcher(node))
      return node;
  }

  return null;
};

HeapProfilerTestRunner.switchToView = function(title, callback) {
  return new Promise(resolve => {
    callback = TestRunner.safeWrap(callback);
    const view = UI.panels.heap_profiler.visibleView;
    view._changePerspectiveAndWait(title).then(callback).then(resolve);
    HeapProfilerTestRunner._currentGrid().scrollContainer.style.height = '10000px';
  });
};

HeapProfilerTestRunner.takeAndOpenSnapshot = async function(generator, callback) {
  callback = TestRunner.safeWrap(callback);
  const snapshot = generator();
  const profileType = Profiler.ProfileTypeRegistry.instance.heapSnapshotProfileType;

  function pushGeneratedSnapshot(reportProgress) {
    if (reportProgress) {
      profileType._reportHeapSnapshotProgress({data: {done: 50, total: 100, finished: false}});
      profileType._reportHeapSnapshotProgress({data: {done: 100, total: 100, finished: true}});
    }
    snapshot.snapshot.typeId = 'HEAP';
    profileType._addHeapSnapshotChunk({data: JSON.stringify(snapshot)});
    return Promise.resolve();
  }

  HeapProfilerTestRunner._takeAndOpenSnapshotCallback = callback;
  TestRunner.override(TestRunner.HeapProfilerAgent, 'takeHeapSnapshot', pushGeneratedSnapshot);
  if (!UI.context.flavor(SDK.HeapProfilerModel))
    await new Promise(resolve => UI.context.addFlavorChangeListener(SDK.HeapProfilerModel, resolve));
  profileType._takeHeapSnapshot();
};

/**
 * @return {!Promise<!Profiler.HeapProfileHeader>}
 */
HeapProfilerTestRunner.takeSnapshotPromise = function() {
  return new Promise(resolve => {
    const heapProfileType = Profiler.ProfileTypeRegistry.instance.heapSnapshotProfileType;
    heapProfileType.addEventListener(Profiler.HeapSnapshotProfileType.SnapshotReceived, finishHeapSnapshot);
    heapProfileType._takeHeapSnapshot();

    function finishHeapSnapshot() {
      const profiles = heapProfileType.getProfiles();
      if (!profiles.length)
        throw 'FAILED: no profiles found.';
      if (profiles.length > 1)
        throw `FAILED: wrong number of recorded profiles was found. profiles.length = ${profiles.length}`;
      const profile = profiles[0];
      UI.panels.heap_profiler.showProfile(profile);

      const dataGrid = HeapProfilerTestRunner.currentProfileView()._dataGrid;
      dataGrid.addEventListener(Profiler.HeapSnapshotSortableDataGrid.Events.SortingComplete, sortingComplete, null);

      function sortingComplete() {
        dataGrid.removeEventListener(
            Profiler.HeapSnapshotSortableDataGrid.Events.SortingComplete, sortingComplete, null);
        resolve(profile);
      }
    }
  });
};

HeapProfilerTestRunner.viewColumns = function() {
  return HeapProfilerTestRunner._currentGrid()._columnsArray;
};

HeapProfilerTestRunner.currentProfileView = function() {
  return UI.panels.heap_profiler.visibleView;
};

HeapProfilerTestRunner._currentGrid = function() {
  return this.currentProfileView()._dataGrid;
};

HeapProfilerTestRunner._snapshotViewShown = function() {
  if (HeapProfilerTestRunner._takeAndOpenSnapshotCallback) {
    const callback = HeapProfilerTestRunner._takeAndOpenSnapshotCallback;
    HeapProfilerTestRunner._takeAndOpenSnapshotCallback = null;
    const dataGrid = this._dataGrid;

    function sortingComplete() {
      dataGrid.removeEventListener(Profiler.HeapSnapshotSortableDataGrid.Events.SortingComplete, sortingComplete, null);
      callback();
    }

    dataGrid.addEventListener(Profiler.HeapSnapshotSortableDataGrid.Events.SortingComplete, sortingComplete, null);
  }
};

HeapProfilerTestRunner.showProfileWhenAdded = function(title) {
  HeapProfilerTestRunner._showProfileWhenAdded = title;
  return new Promise(resolve => HeapProfilerTestRunner._waitUntilProfileViewIsShown(title, resolve));
};

HeapProfilerTestRunner._profileHeaderAdded = function(profile) {
  if (HeapProfilerTestRunner._showProfileWhenAdded === profile.title)
    UI.panels.heap_profiler.showProfile(profile);
};

HeapProfilerTestRunner._waitUntilProfileViewIsShown = function(title, callback) {
  callback = TestRunner.safeWrap(callback);
  const profilesPanel = UI.panels.heap_profiler;

  if (profilesPanel.visibleView && profilesPanel.visibleView.profile &&
      profilesPanel.visibleView._profileHeader.title === title)
    callback(profilesPanel.visibleView);
  else
    HeapProfilerTestRunner._waitUntilProfileViewIsShownCallback = {title: title, callback: callback};

};

HeapProfilerTestRunner._profileViewRefresh = function() {
  if (HeapProfilerTestRunner._waitUntilProfileViewIsShownCallback &&
      HeapProfilerTestRunner._waitUntilProfileViewIsShownCallback.title === this._profileHeader.title) {
    const callback = HeapProfilerTestRunner._waitUntilProfileViewIsShownCallback;
    delete HeapProfilerTestRunner._waitUntilProfileViewIsShownCallback;
    callback.callback(this);
  }
};

HeapProfilerTestRunner.startSamplingHeapProfiler = async function() {
  if (!UI.context.flavor(SDK.HeapProfilerModel))
    await new Promise(resolve => UI.context.addFlavorChangeListener(SDK.HeapProfilerModel, resolve));
  Profiler.SamplingHeapProfileType.instance.startRecordingProfile();
};

HeapProfilerTestRunner.stopSamplingHeapProfiler = function() {
  Profiler.SamplingHeapProfileType.instance.stopRecordingProfile();
};
