/*
 * Copyright (C) 2011 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @implements {Profiler.ProfileType.DataDisplayDelegate}
 * @implements {UI.Searchable}
 * @unrestricted
 */
Profiler.HeapSnapshotView = class extends UI.SimpleView {
  /**
   * @param {!Profiler.ProfileType.DataDisplayDelegate} dataDisplayDelegate
   * @param {!Profiler.HeapProfileHeader} profile
   */
  constructor(dataDisplayDelegate, profile) {
    super(Common.UIString('Heap Snapshot'));

    this.element.classList.add('heap-snapshot-view');
    this._profile = profile;
    this._linkifier = new Components.Linkifier();
    const profileType = profile.profileType();

    profileType.addEventListener(Profiler.HeapSnapshotProfileType.SnapshotReceived, this._onReceiveSnapshot, this);
    profileType.addEventListener(Profiler.ProfileType.Events.RemoveProfileHeader, this._onProfileHeaderRemoved, this);

    const isHeapTimeline = profileType.id === Profiler.TrackingHeapSnapshotProfileType.TypeId;
    if (isHeapTimeline) {
      this._createOverview();
    }

    this._parentDataDisplayDelegate = dataDisplayDelegate;

    this._searchableView = new UI.SearchableView(this);
    this._searchableView.show(this.element);

    this._splitWidget = new UI.SplitWidget(false, true, 'heapSnapshotSplitViewState', 200, 200);
    this._splitWidget.show(this._searchableView.element);

    const heapProfilerModel = profile.heapProfilerModel();
    this._containmentDataGrid = new Profiler.HeapSnapshotContainmentDataGrid(heapProfilerModel, this);
    this._containmentDataGrid.addEventListener(DataGrid.DataGrid.Events.SelectedNode, this._selectionChanged, this);
    this._containmentWidget = this._containmentDataGrid.asWidget();
    this._containmentWidget.setMinimumSize(50, 25);

    this._statisticsView = new Profiler.HeapSnapshotStatisticsView();

    this._constructorsDataGrid = new Profiler.HeapSnapshotConstructorsDataGrid(heapProfilerModel, this);
    this._constructorsDataGrid.addEventListener(DataGrid.DataGrid.Events.SelectedNode, this._selectionChanged, this);
    this._constructorsWidget = this._constructorsDataGrid.asWidget();
    this._constructorsWidget.setMinimumSize(50, 25);

    this._diffDataGrid = new Profiler.HeapSnapshotDiffDataGrid(heapProfilerModel, this);
    this._diffDataGrid.addEventListener(DataGrid.DataGrid.Events.SelectedNode, this._selectionChanged, this);
    this._diffWidget = this._diffDataGrid.asWidget();
    this._diffWidget.setMinimumSize(50, 25);

    if (isHeapTimeline) {
      this._allocationDataGrid = new Profiler.AllocationDataGrid(heapProfilerModel, this);
      this._allocationDataGrid.addEventListener(
          DataGrid.DataGrid.Events.SelectedNode, this._onSelectAllocationNode, this);
      this._allocationWidget = this._allocationDataGrid.asWidget();
      this._allocationWidget.setMinimumSize(50, 25);

      this._allocationStackView = new Profiler.HeapAllocationStackView(heapProfilerModel);
      this._allocationStackView.setMinimumSize(50, 25);

      this._tabbedPane = new UI.TabbedPane();
    }

    this._retainmentDataGrid = new Profiler.HeapSnapshotRetainmentDataGrid(heapProfilerModel, this);
    this._retainmentWidget = this._retainmentDataGrid.asWidget();
    this._retainmentWidget.setMinimumSize(50, 21);
    this._retainmentWidget.element.classList.add('retaining-paths-view');

    let splitWidgetResizer;
    if (this._allocationStackView) {
      this._tabbedPane = new UI.TabbedPane();

      this._tabbedPane.appendTab('retainers', Common.UIString('Retainers'), this._retainmentWidget);
      this._tabbedPane.appendTab('allocation-stack', Common.UIString('Allocation stack'), this._allocationStackView);

      splitWidgetResizer = this._tabbedPane.headerElement();
      this._objectDetailsView = this._tabbedPane;
    } else {
      const retainmentViewHeader = createElementWithClass('div', 'heap-snapshot-view-resizer');
      const retainingPathsTitleDiv = retainmentViewHeader.createChild('div', 'title');
      const retainingPathsTitle = retainingPathsTitleDiv.createChild('span');
      retainingPathsTitle.textContent = Common.UIString('Retainers');

      splitWidgetResizer = retainmentViewHeader;
      this._objectDetailsView = new UI.VBox();
      this._objectDetailsView.element.appendChild(retainmentViewHeader);
      this._retainmentWidget.show(this._objectDetailsView.element);
    }
    this._splitWidget.hideDefaultResizer();
    this._splitWidget.installResizer(splitWidgetResizer);

    this._retainmentDataGrid.addEventListener(
        DataGrid.DataGrid.Events.SelectedNode, this._inspectedObjectChanged, this);
    this._retainmentDataGrid.reset();

    this._perspectives = [];
    this._comparisonPerspective = new Profiler.HeapSnapshotView.ComparisonPerspective();
    this._perspectives.push(new Profiler.HeapSnapshotView.SummaryPerspective());
    if (profile.profileType() !== Profiler.ProfileTypeRegistry.instance.trackingHeapSnapshotProfileType) {
      this._perspectives.push(this._comparisonPerspective);
    }
    this._perspectives.push(new Profiler.HeapSnapshotView.ContainmentPerspective());
    if (this._allocationWidget) {
      this._perspectives.push(new Profiler.HeapSnapshotView.AllocationPerspective());
    }
    this._perspectives.push(new Profiler.HeapSnapshotView.StatisticsPerspective());

    this._perspectiveSelect = new UI.ToolbarComboBox(this._onSelectedPerspectiveChanged.bind(this), ls`Perspective`);
    this._updatePerspectiveOptions();

    this._baseSelect = new UI.ToolbarComboBox(this._changeBase.bind(this), ls`Base snapshot`);
    this._baseSelect.setVisible(false);
    this._updateBaseOptions();

    this._filterSelect = new UI.ToolbarComboBox(this._changeFilter.bind(this), ls`Filter`);
    this._filterSelect.setVisible(false);
    this._updateFilterOptions();

    this._classNameFilter = new UI.ToolbarInput(ls`Class filter`);
    this._classNameFilter.setVisible(false);
    this._constructorsDataGrid.setNameFilter(this._classNameFilter);
    this._diffDataGrid.setNameFilter(this._classNameFilter);

    this._selectedSizeText = new UI.ToolbarText();

    this._popoverHelper = new UI.PopoverHelper(this.element, this._getPopoverRequest.bind(this));
    this._popoverHelper.setDisableOnClick(true);
    this._popoverHelper.setHasPadding(true);
    this.element.addEventListener('scroll', this._popoverHelper.hidePopover.bind(this._popoverHelper), true);

    this._currentPerspectiveIndex = 0;
    this._currentPerspective = this._perspectives[0];
    this._currentPerspective.activate(this);
    this._dataGrid = this._currentPerspective.masterGrid(this);

    this._populate();
    this._searchThrottler = new Common.Throttler(0);

    for (const existingProfile of this._profiles()) {
      existingProfile.addEventListener(Profiler.ProfileHeader.Events.ProfileTitleChanged, this._updateControls, this);
    }
  }

  _createOverview() {
    const profileType = this._profile.profileType();
    this._trackingOverviewGrid = new Profiler.HeapTimelineOverview();
    this._trackingOverviewGrid.addEventListener(
        Profiler.HeapTimelineOverview.IdsRangeChanged, this._onIdsRangeChanged.bind(this));
    if (!this._profile.fromFile() && profileType.profileBeingRecorded() === this._profile) {
      profileType.addEventListener(
          Profiler.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._onHeapStatsUpdate, this);
      profileType.addEventListener(
          Profiler.TrackingHeapSnapshotProfileType.TrackingStopped, this._onStopTracking, this);
      this._trackingOverviewGrid.start();
    }
  }

  _onStopTracking() {
    this._profile.profileType().removeEventListener(
        Profiler.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._onHeapStatsUpdate, this);
    this._profile.profileType().removeEventListener(
        Profiler.TrackingHeapSnapshotProfileType.TrackingStopped, this._onStopTracking, this);
    if (this._trackingOverviewGrid) {
      this._trackingOverviewGrid.stop();
    }
  }

  /**
   * @param {!Common.Event} event
   */
  _onHeapStatsUpdate(event) {
    const samples = event.data;
    if (samples) {
      this._trackingOverviewGrid.setSamples(event.data);
    }
  }

  /**
   * @return {!UI.SearchableView}
   */
  searchableView() {
    return this._searchableView;
  }

  /**
   * @override
   * @param {?Profiler.ProfileHeader} profile
   * @return {?UI.Widget}
   */
  showProfile(profile) {
    return this._parentDataDisplayDelegate.showProfile(profile);
  }

  /**
   * @override
   * @param {!Protocol.HeapProfiler.HeapSnapshotObjectId} snapshotObjectId
   * @param {string} perspectiveName
   */
  showObject(snapshotObjectId, perspectiveName) {
    if (snapshotObjectId <= this._profile.maxJSObjectId) {
      this.selectLiveObject(perspectiveName, snapshotObjectId);
    } else {
      this._parentDataDisplayDelegate.showObject(snapshotObjectId, perspectiveName);
    }
  }

  /**
   * @override
   * @param {number} nodeIndex
   * @return {!Promise<?Element>}
   */
  async linkifyObject(nodeIndex) {
    const heapProfilerModel = this._profile.heapProfilerModel();
    // heapProfilerModel is null if snapshot was loaded from file
    if (!heapProfilerModel) {
      return null;
    }
    const location = await this._profile.getLocation(nodeIndex);
    if (!location) {
      return null;
    }
    const debuggerModel = heapProfilerModel.runtimeModel().debuggerModel();
    const rawLocation = debuggerModel.createRawLocationByScriptId(
        String(location.scriptId), location.lineNumber, location.columnNumber);
    if (!rawLocation) {
      return null;
    }
    const sourceURL = rawLocation.script() && rawLocation.script().sourceURL;
    return sourceURL && this._linkifier ? this._linkifier.linkifyRawLocation(rawLocation, sourceURL) : null;
  }

  async _populate() {
    const heapSnapshotProxy = await this._profile._loadPromise;

    this._retrieveStatistics(heapSnapshotProxy);
    this._dataGrid.setDataSource(heapSnapshotProxy);

    if (this._profile.profileType().id === Profiler.TrackingHeapSnapshotProfileType.TypeId &&
        this._profile.fromFile()) {
      const samples = await heapSnapshotProxy.getSamples();
      if (samples) {
        console.assert(samples.timestamps.length);
        const profileSamples = new Profiler.HeapTimelineOverview.Samples();
        profileSamples.sizes = samples.sizes;
        profileSamples.ids = samples.lastAssignedIds;
        profileSamples.timestamps = samples.timestamps;
        profileSamples.max = samples.sizes;
        profileSamples.totalTime = Math.max(samples.timestamps.peekLast(), 10000);
        this._trackingOverviewGrid.setSamples(profileSamples);
      }
    }

    const list = this._profiles();
    const profileIndex = list.indexOf(this._profile);
    this._baseSelect.setSelectedIndex(Math.max(0, profileIndex - 1));
    if (this._trackingOverviewGrid) {
      this._trackingOverviewGrid.updateGrid();
    }
  }

  /**
   * @param {!Profiler.HeapSnapshotProxy} heapSnapshotProxy
   * @return {!Promise<!HeapSnapshotModel.Statistics>}
   */
  async _retrieveStatistics(heapSnapshotProxy) {
    const statistics = await heapSnapshotProxy.getStatistics();
    this._statisticsView.setTotal(statistics.total);
    this._statisticsView.addRecord(statistics.code, Common.UIString('Code'), '#f77');
    this._statisticsView.addRecord(statistics.strings, Common.UIString('Strings'), '#5e5');
    this._statisticsView.addRecord(statistics.jsArrays, Common.UIString('JS Arrays'), '#7af');
    this._statisticsView.addRecord(statistics.native, Common.UIString('Typed Arrays'), '#fc5');
    this._statisticsView.addRecord(statistics.system, Common.UIString('System Objects'), '#98f');
    return statistics;
  }

  /**
   * @param {!Common.Event} event
   */
  _onIdsRangeChanged(event) {
    const minId = event.data.minId;
    const maxId = event.data.maxId;
    this._selectedSizeText.setText(Common.UIString('Selected size: %s', Number.bytesToString(event.data.size)));
    if (this._constructorsDataGrid.snapshot) {
      this._constructorsDataGrid.setSelectionRange(minId, maxId);
    }
  }

  /**
   * @override
   * @return {!Array<!UI.ToolbarItem>}
   */
  syncToolbarItems() {
    const result = [this._perspectiveSelect, this._classNameFilter];
    if (this._profile.profileType() !== Profiler.ProfileTypeRegistry.instance.trackingHeapSnapshotProfileType) {
      result.push(this._baseSelect, this._filterSelect);
    }
    result.push(this._selectedSizeText);
    return result;
  }

  /**
   * @override
   */
  willHide() {
    this._currentSearchResultIndex = -1;
    this._popoverHelper.hidePopover();
  }

  /**
   * @override
   * @return {boolean}
   */
  supportsCaseSensitiveSearch() {
    return true;
  }

  /**
   * @override
   * @return {boolean}
   */
  supportsRegexSearch() {
    return false;
  }

  /**
   * @override
   */
  searchCanceled() {
    this._currentSearchResultIndex = -1;
    this._searchResults = [];
  }

  /**
   * @param {?Profiler.HeapSnapshotGridNode} node
   */
  _selectRevealedNode(node) {
    if (node) {
      node.select();
    }
  }

  /**
   * @override
   * @param {!UI.SearchableView.SearchConfig} searchConfig
   * @param {boolean} shouldJump
   * @param {boolean=} jumpBackwards
   */
  performSearch(searchConfig, shouldJump, jumpBackwards) {
    const nextQuery = new HeapSnapshotModel.SearchConfig(
        searchConfig.query.trim(), searchConfig.caseSensitive, searchConfig.isRegex, shouldJump,
        jumpBackwards || false);

    this._searchThrottler.schedule(this._performSearch.bind(this, nextQuery));
  }

  /**
   * @param {!HeapSnapshotModel.SearchConfig} nextQuery
   * @return {!Promise}
   */
  async _performSearch(nextQuery) {
    // Call searchCanceled since it will reset everything we need before doing a new search.
    this.searchCanceled();

    if (!this._currentPerspective.supportsSearch()) {
      return;
    }

    this.currentQuery = nextQuery;
    const query = nextQuery.query.trim();

    if (!query) {
      return;
    }

    if (query.charAt(0) === '@') {
      const snapshotNodeId = parseInt(query.substring(1), 10);
      if (isNaN(snapshotNodeId)) {
        return;
      }
      const node = await this._dataGrid.revealObjectByHeapSnapshotId(String(snapshotNodeId));
      this._selectRevealedNode(node);
      return;
    }

    this._searchResults = await this._profile._snapshotProxy.search(this.currentQuery, this._dataGrid.nodeFilter());

    this._searchableView.updateSearchMatchesCount(this._searchResults.length);
    if (this._searchResults.length) {
      this._currentSearchResultIndex = nextQuery.jumpBackwards ? this._searchResults.length - 1 : 0;
    }
    await this._jumpToSearchResult(this._currentSearchResultIndex);
  }

  /**
   * @override
   */
  jumpToNextSearchResult() {
    if (!this._searchResults.length) {
      return;
    }
    this._currentSearchResultIndex = (this._currentSearchResultIndex + 1) % this._searchResults.length;
    this._searchThrottler.schedule(this._jumpToSearchResult.bind(this, this._currentSearchResultIndex));
  }

  /**
   * @override
   */
  jumpToPreviousSearchResult() {
    if (!this._searchResults.length) {
      return;
    }
    this._currentSearchResultIndex =
        (this._currentSearchResultIndex + this._searchResults.length - 1) % this._searchResults.length;
    this._searchThrottler.schedule(this._jumpToSearchResult.bind(this, this._currentSearchResultIndex));
  }

  /**
   * @param {number} searchResultIndex
   * @return {!Promise}
   */
  async _jumpToSearchResult(searchResultIndex) {
    this._searchableView.updateCurrentMatchIndex(searchResultIndex);
    if (searchResultIndex === -1) {
      return;
    }
    const node = await this._dataGrid.revealObjectByHeapSnapshotId(String(this._searchResults[searchResultIndex]));
    this._selectRevealedNode(node);
  }

  refreshVisibleData() {
    if (!this._dataGrid) {
      return;
    }
    let child = this._dataGrid.rootNode().children[0];
    while (child) {
      child.refresh();
      child = child.traverseNextNode(false, null, true);
    }
  }

  _changeBase() {
    if (this._baseProfile === this._profiles()[this._baseSelect.selectedIndex()]) {
      return;
    }

    this._baseProfile = this._profiles()[this._baseSelect.selectedIndex()];
    const dataGrid = /** @type {!Profiler.HeapSnapshotDiffDataGrid} */ (this._dataGrid);
    // Change set base data source only if main data source is already set.
    if (dataGrid.snapshot) {
      this._baseProfile._loadPromise.then(dataGrid.setBaseDataSource.bind(dataGrid));
    }

    if (!this.currentQuery || !this._searchResults) {
      return;
    }

    // The current search needs to be performed again. First negate out previous match
    // count by calling the search finished callback with a negative number of matches.
    // Then perform the search again with the same query and callback.
    this.performSearch(this.currentQuery, false);
  }

  _changeFilter() {
    const profileIndex = this._filterSelect.selectedIndex() - 1;
    this._dataGrid.filterSelectIndexChanged(this._profiles(), profileIndex);

    if (!this.currentQuery || !this._searchResults) {
      return;
    }

    // The current search needs to be performed again. First negate out previous match
    // count by calling the search finished callback with a negative number of matches.
    // Then perform the search again with the same query and callback.
    this.performSearch(this.currentQuery, false);
  }

  /**
   * @return {!Array.<!Profiler.ProfileHeader>}
   */
  _profiles() {
    return this._profile.profileType().getProfiles();
  }

  /**
   * @param {!Common.Event} event
   */
  _selectionChanged(event) {
    const selectedNode = /** @type {!Profiler.HeapSnapshotGridNode} */ (event.data);
    this._setSelectedNodeForDetailsView(selectedNode);
    this._inspectedObjectChanged(event);
  }

  /**
   * @param {!Common.Event} event
   */
  _onSelectAllocationNode(event) {
    const selectedNode = /** @type {!DataGrid.DataGridNode} */ (event.data);
    this._constructorsDataGrid.setAllocationNodeId(selectedNode.allocationNodeId());
    this._setSelectedNodeForDetailsView(null);
  }

  /**
   * @param {!Common.Event} event
   */
  _inspectedObjectChanged(event) {
    const selectedNode = /** @type {!DataGrid.DataGridNode} */ (event.data);
    const heapProfilerModel = this._profile.heapProfilerModel();
    if (heapProfilerModel && selectedNode instanceof Profiler.HeapSnapshotGenericObjectNode) {
      heapProfilerModel.addInspectedHeapObject(String(selectedNode.snapshotNodeId));
    }
  }

  /**
   * @param {?Profiler.HeapSnapshotGridNode} nodeItem
   */
  _setSelectedNodeForDetailsView(nodeItem) {
    const dataSource = nodeItem && nodeItem.retainersDataSource();
    if (dataSource) {
      this._retainmentDataGrid.setDataSource(dataSource.snapshot, dataSource.snapshotNodeIndex);
      if (this._allocationStackView) {
        this._allocationStackView.setAllocatedObject(dataSource.snapshot, dataSource.snapshotNodeIndex);
      }
    } else {
      if (this._allocationStackView) {
        this._allocationStackView.clear();
      }
      this._retainmentDataGrid.reset();
    }
  }

  /**
   * @param {string} perspectiveTitle
   * @return {!Promise}
   */
  _changePerspectiveAndWait(perspectiveTitle) {
    const perspectiveIndex = this._perspectives.findIndex(perspective => perspective.title() === perspectiveTitle);
    if (perspectiveIndex === -1 || this._currentPerspectiveIndex === perspectiveIndex) {
      return Promise.resolve();
    }

    const promise = this._perspectives[perspectiveIndex].masterGrid(this).once(
        Profiler.HeapSnapshotSortableDataGrid.Events.ContentShown);

    const option = this._perspectiveSelect.options().find(option => option.value === String(perspectiveIndex));
    this._perspectiveSelect.select(/** @type {!Element} */ (option));
    this._changePerspective(perspectiveIndex);
    return promise;
  }

  async _updateDataSourceAndView() {
    const dataGrid = this._dataGrid;
    if (!dataGrid || dataGrid.snapshot) {
      return;
    }

    const snapshotProxy = await this._profile._loadPromise;

    if (this._dataGrid !== dataGrid) {
      return;
    }
    if (dataGrid.snapshot !== snapshotProxy) {
      dataGrid.setDataSource(snapshotProxy);
    }
    if (dataGrid !== this._diffDataGrid) {
      return;
    }
    if (!this._baseProfile) {
      this._baseProfile = this._profiles()[this._baseSelect.selectedIndex()];
    }

    const baseSnapshotProxy = await this._baseProfile._loadPromise;

    if (this._diffDataGrid.baseSnapshot !== baseSnapshotProxy) {
      this._diffDataGrid.setBaseDataSource(baseSnapshotProxy);
    }
  }

  /**
   * @param {!Event} event
   */
  _onSelectedPerspectiveChanged(event) {
    this._changePerspective(event.target.selectedOptions[0].value);
  }

  /**
   * @param {number} selectedIndex
   */
  _changePerspective(selectedIndex) {
    if (selectedIndex === this._currentPerspectiveIndex) {
      return;
    }

    this._currentPerspectiveIndex = selectedIndex;

    this._currentPerspective.deactivate(this);
    const perspective = this._perspectives[selectedIndex];
    this._currentPerspective = perspective;
    this._dataGrid = perspective.masterGrid(this);
    perspective.activate(this);

    this.refreshVisibleData();
    if (this._dataGrid) {
      this._dataGrid.updateWidths();
    }

    this._updateDataSourceAndView();

    if (!this.currentQuery || !this._searchResults) {
      return;
    }

    // The current search needs to be performed again. First negate out previous match
    // count by calling the search finished callback with a negative number of matches.
    // Then perform the search again the with same query and callback.
    this.performSearch(this.currentQuery, false);
  }

  /**
   * @param {string} perspectiveName
   * @param {!Protocol.HeapProfiler.HeapSnapshotObjectId} snapshotObjectId
   */
  async selectLiveObject(perspectiveName, snapshotObjectId) {
    await this._changePerspectiveAndWait(perspectiveName);
    const node = await this._dataGrid.revealObjectByHeapSnapshotId(snapshotObjectId);
    if (node) {
      node.select();
    } else {
      Common.console.error('Cannot find corresponding heap snapshot node');
    }
  }

  /**
   * @param {!Event} event
   * @return {?UI.PopoverRequest}
   */
  _getPopoverRequest(event) {
    const span = event.target.enclosingNodeOrSelfWithNodeName('span');
    const row = event.target.enclosingNodeOrSelfWithNodeName('tr');
    const heapProfilerModel = this._profile.heapProfilerModel();
    if (!row || !span || !heapProfilerModel) {
      return null;
    }
    const node = row._dataGridNode;
    let objectPopoverHelper;
    return {
      box: span.boxInWindow(),
      show: async popover => {
        const remoteObject = await node.queryObjectContent(heapProfilerModel, 'popover');
        if (!remoteObject) {
          return false;
        }
        objectPopoverHelper = await ObjectUI.ObjectPopoverHelper.buildObjectPopover(remoteObject, popover);
        if (!objectPopoverHelper) {
          heapProfilerModel.runtimeModel().releaseObjectGroup('popover');
          return false;
        }
        return true;
      },
      hide: () => {
        heapProfilerModel.runtimeModel().releaseObjectGroup('popover');
        objectPopoverHelper.dispose();
      }
    };
  }

  _updatePerspectiveOptions() {
    const multipleSnapshots = this._profiles().length > 1;
    this._perspectiveSelect.removeOptions();
    this._perspectives.forEach((perspective, index) => {
      if (multipleSnapshots || perspective !== this._comparisonPerspective) {
        this._perspectiveSelect.createOption(perspective.title(), String(index));
      }
    });
  }

  _updateBaseOptions() {
    const list = this._profiles();
    const selectedIndex = this._baseSelect.selectedIndex();

    this._baseSelect.removeOptions();
    for (const item of list) {
      this._baseSelect.createOption(item.title);
    }

    if (selectedIndex > -1) {
      this._baseSelect.setSelectedIndex(selectedIndex);
    }
  }

  _updateFilterOptions() {
    const list = this._profiles();
    const selectedIndex = this._filterSelect.selectedIndex();

    this._filterSelect.removeOptions();
    this._filterSelect.createOption(Common.UIString('All objects'));
    for (let i = 0; i < list.length; ++i) {
      let title;
      if (!i) {
        title = Common.UIString('Objects allocated before %s', list[i].title);
      } else {
        title = Common.UIString('Objects allocated between %s and %s', list[i - 1].title, list[i].title);
      }
      this._filterSelect.createOption(title);
    }

    if (selectedIndex > -1) {
      this._filterSelect.setSelectedIndex(selectedIndex);
    }
  }

  _updateControls() {
    this._updatePerspectiveOptions();
    this._updateBaseOptions();
    this._updateFilterOptions();
  }

  /**
   * @param {!Common.Event} event
   */
  _onReceiveSnapshot(event) {
    this._updateControls();
    const profile = event.data;
    profile.addEventListener(Profiler.ProfileHeader.Events.ProfileTitleChanged, this._updateControls, this);
  }

  /**
   * @param {!Common.Event} event
   */
  _onProfileHeaderRemoved(event) {
    const profile = event.data;
    profile.removeEventListener(Profiler.ProfileHeader.Events.ProfileTitleChanged, this._updateControls, this);

    if (this._profile === profile) {
      this.detach();
      this._profile.profileType().removeEventListener(
          Profiler.HeapSnapshotProfileType.SnapshotReceived, this._onReceiveSnapshot, this);
      this._profile.profileType().removeEventListener(
          Profiler.ProfileType.Events.RemoveProfileHeader, this._onProfileHeaderRemoved, this);
      this.dispose();
    } else {
      this._updateControls();
    }
  }

  dispose() {
    this._linkifier.dispose();
    this._popoverHelper.dispose();
    if (this._allocationStackView) {
      this._allocationStackView.clear();
      this._allocationDataGrid.dispose();
    }
    this._onStopTracking();
    if (this._trackingOverviewGrid) {
      this._trackingOverviewGrid.removeEventListener(
          Profiler.HeapTimelineOverview.IdsRangeChanged, this._onIdsRangeChanged.bind(this));
    }
  }
};

/**
 * @unrestricted
 */
Profiler.HeapSnapshotView.Perspective = class {
  /**
   * @param {string} title
   */
  constructor(title) {
    this._title = title;
  }

  /**
   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
   */
  activate(heapSnapshotView) {
  }

  /**
   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
   */
  deactivate(heapSnapshotView) {
    heapSnapshotView._baseSelect.setVisible(false);
    heapSnapshotView._filterSelect.setVisible(false);
    heapSnapshotView._classNameFilter.setVisible(false);
    if (heapSnapshotView._trackingOverviewGrid) {
      heapSnapshotView._trackingOverviewGrid.detach();
    }
    if (heapSnapshotView._allocationWidget) {
      heapSnapshotView._allocationWidget.detach();
    }
    if (heapSnapshotView._statisticsView) {
      heapSnapshotView._statisticsView.detach();
    }

    heapSnapshotView._splitWidget.detach();
    heapSnapshotView._splitWidget.detachChildWidgets();
  }

  /**
   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
   * @return {?DataGrid.DataGrid}
   */
  masterGrid(heapSnapshotView) {
    return null;
  }

  /**
   * @return {string}
   */
  title() {
    return this._title;
  }

  /**
   * @return {boolean}
   */
  supportsSearch() {
    return false;
  }
};

/**
 * @unrestricted
 */
Profiler.HeapSnapshotView.SummaryPerspective = class extends Profiler.HeapSnapshotView.Perspective {
  constructor() {
    super(Common.UIString('Summary'));
  }

  /**
   * @override
   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
   */
  activate(heapSnapshotView) {
    heapSnapshotView._splitWidget.setMainWidget(heapSnapshotView._constructorsWidget);
    heapSnapshotView._splitWidget.setSidebarWidget(heapSnapshotView._objectDetailsView);
    heapSnapshotView._splitWidget.show(heapSnapshotView._searchableView.element);
    heapSnapshotView._filterSelect.setVisible(true);
    heapSnapshotView._classNameFilter.setVisible(true);
    if (!heapSnapshotView._trackingOverviewGrid) {
      return;
    }
    heapSnapshotView._trackingOverviewGrid.show(
        heapSnapshotView._searchableView.element, heapSnapshotView._splitWidget.element);
    heapSnapshotView._trackingOverviewGrid.update();
    heapSnapshotView._trackingOverviewGrid.updateGrid();
  }

  /**
   * @override
   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
   * @return {?DataGrid.DataGrid}
   */
  masterGrid(heapSnapshotView) {
    return heapSnapshotView._constructorsDataGrid;
  }

  /**
   * @override
   * @return {boolean}
   */
  supportsSearch() {
    return true;
  }
};

/**
 * @unrestricted
 */
Profiler.HeapSnapshotView.ComparisonPerspective = class extends Profiler.HeapSnapshotView.Perspective {
  constructor() {
    super(Common.UIString('Comparison'));
  }

  /**
   * @override
   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
   */
  activate(heapSnapshotView) {
    heapSnapshotView._splitWidget.setMainWidget(heapSnapshotView._diffWidget);
    heapSnapshotView._splitWidget.setSidebarWidget(heapSnapshotView._objectDetailsView);
    heapSnapshotView._splitWidget.show(heapSnapshotView._searchableView.element);
    heapSnapshotView._baseSelect.setVisible(true);
    heapSnapshotView._classNameFilter.setVisible(true);
  }

  /**
   * @override
   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
   * @return {?DataGrid.DataGrid}
   */
  masterGrid(heapSnapshotView) {
    return heapSnapshotView._diffDataGrid;
  }

  /**
   * @override
   * @return {boolean}
   */
  supportsSearch() {
    return true;
  }
};

/**
 * @unrestricted
 */
Profiler.HeapSnapshotView.ContainmentPerspective = class extends Profiler.HeapSnapshotView.Perspective {
  constructor() {
    super(Common.UIString('Containment'));
  }

  /**
   * @override
   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
   */
  activate(heapSnapshotView) {
    heapSnapshotView._splitWidget.setMainWidget(heapSnapshotView._containmentWidget);
    heapSnapshotView._splitWidget.setSidebarWidget(heapSnapshotView._objectDetailsView);
    heapSnapshotView._splitWidget.show(heapSnapshotView._searchableView.element);
  }

  /**
   * @override
   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
   * @return {?DataGrid.DataGrid}
   */
  masterGrid(heapSnapshotView) {
    return heapSnapshotView._containmentDataGrid;
  }
};

/**
 * @unrestricted
 */
Profiler.HeapSnapshotView.AllocationPerspective = class extends Profiler.HeapSnapshotView.Perspective {
  constructor() {
    super(Common.UIString('Allocation'));
    this._allocationSplitWidget = new UI.SplitWidget(false, true, 'heapSnapshotAllocationSplitViewState', 200, 200);
    this._allocationSplitWidget.setSidebarWidget(new UI.VBox());
  }

  /**
   * @override
   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
   */
  activate(heapSnapshotView) {
    this._allocationSplitWidget.setMainWidget(heapSnapshotView._allocationWidget);
    heapSnapshotView._splitWidget.setMainWidget(heapSnapshotView._constructorsWidget);
    heapSnapshotView._splitWidget.setSidebarWidget(heapSnapshotView._objectDetailsView);

    const allocatedObjectsView = new UI.VBox();
    const resizer = createElementWithClass('div', 'heap-snapshot-view-resizer');
    const title = resizer.createChild('div', 'title').createChild('span');
    title.textContent = Common.UIString('Live objects');
    this._allocationSplitWidget.hideDefaultResizer();
    this._allocationSplitWidget.installResizer(resizer);
    allocatedObjectsView.element.appendChild(resizer);
    heapSnapshotView._splitWidget.show(allocatedObjectsView.element);
    this._allocationSplitWidget.setSidebarWidget(allocatedObjectsView);

    this._allocationSplitWidget.show(heapSnapshotView._searchableView.element);

    heapSnapshotView._constructorsDataGrid.clear();
    const selectedNode = heapSnapshotView._allocationDataGrid.selectedNode;
    if (selectedNode) {
      heapSnapshotView._constructorsDataGrid.setAllocationNodeId(selectedNode.allocationNodeId());
    }
  }

  /**
   * @override
   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
   */
  deactivate(heapSnapshotView) {
    this._allocationSplitWidget.detach();
    super.deactivate(heapSnapshotView);
  }

  /**
   * @override
   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
   * @return {?DataGrid.DataGrid}
   */
  masterGrid(heapSnapshotView) {
    return heapSnapshotView._allocationDataGrid;
  }
};

/**
 * @unrestricted
 */
Profiler.HeapSnapshotView.StatisticsPerspective = class extends Profiler.HeapSnapshotView.Perspective {
  constructor() {
    super(Common.UIString('Statistics'));
  }

  /**
   * @override
   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
   */
  activate(heapSnapshotView) {
    heapSnapshotView._statisticsView.show(heapSnapshotView._searchableView.element);
  }

  /**
   * @override
   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
   * @return {?DataGrid.DataGrid}
   */
  masterGrid(heapSnapshotView) {
    return null;
  }
};

/**
 * @implements {SDK.SDKModelObserver<!SDK.HeapProfilerModel>}
 * @unrestricted
 */
Profiler.HeapSnapshotProfileType = class extends Profiler.ProfileType {
  /**
   * @param {string=} id
   * @param {string=} title
   */
  constructor(id, title) {
    super(id || Profiler.HeapSnapshotProfileType.TypeId, title || ls`Heap snapshot`);
    SDK.targetManager.observeModels(SDK.HeapProfilerModel, this);
    SDK.targetManager.addModelListener(
        SDK.HeapProfilerModel, SDK.HeapProfilerModel.Events.ResetProfiles, this._resetProfiles, this);
    SDK.targetManager.addModelListener(
        SDK.HeapProfilerModel, SDK.HeapProfilerModel.Events.AddHeapSnapshotChunk, this._addHeapSnapshotChunk, this);
    SDK.targetManager.addModelListener(
        SDK.HeapProfilerModel, SDK.HeapProfilerModel.Events.ReportHeapSnapshotProgress,
        this._reportHeapSnapshotProgress, this);
  }

  /**
   * @override
   * @param {!SDK.HeapProfilerModel} heapProfilerModel
   */
  modelAdded(heapProfilerModel) {
    heapProfilerModel.enable();
  }

  /**
   * @override
   * @param {!SDK.HeapProfilerModel} heapProfilerModel
   */
  modelRemoved(heapProfilerModel) {
  }

  /**
   * @override
   * @return {!Array<!Profiler.HeapProfileHeader>}
   */
  getProfiles() {
    return /** @type {!Array<!Profiler.HeapProfileHeader>} */ (super.getProfiles());
  }

  /**
   * @override
   * @return {string}
   */
  fileExtension() {
    return '.heapsnapshot';
  }

  /**
   * @override
   */
  get buttonTooltip() {
    return Common.UIString('Take heap snapshot');
  }

  /**
   * @override
   * @return {boolean}
   */
  isInstantProfile() {
    return true;
  }

  /**
   * @override
   * @return {boolean}
   */
  buttonClicked() {
    this._takeHeapSnapshot();
    Host.userMetrics.actionTaken(Host.UserMetrics.Action.ProfilesHeapProfileTaken);
    return false;
  }

  /**
   * @override
   */
  get treeItemTitle() {
    return Common.UIString('HEAP SNAPSHOTS');
  }

  /**
   * @override
   */
  get description() {
    return Common.UIString(
        'Heap snapshot profiles show memory distribution among your page\'s JavaScript objects and related DOM nodes.');
  }

  /**
   * @override
   * @param {string} title
   * @return {!Profiler.ProfileHeader}
   */
  createProfileLoadedFromFile(title) {
    return new Profiler.HeapProfileHeader(null, this, title);
  }

  async _takeHeapSnapshot() {
    if (this.profileBeingRecorded()) {
      return;
    }
    const heapProfilerModel = UI.context.flavor(SDK.HeapProfilerModel);
    if (!heapProfilerModel) {
      return;
    }

    let profile = new Profiler.HeapProfileHeader(heapProfilerModel, this);
    this.setProfileBeingRecorded(profile);
    this.addProfile(profile);
    profile.updateStatus(Common.UIString('Snapshotting\u2026'));

    await heapProfilerModel.takeHeapSnapshot(true);
    // ------------ ASYNC ------------
    profile = this.profileBeingRecorded();
    profile.title = Common.UIString('Snapshot %d', profile.uid);
    profile._finishLoad();
    this.setProfileBeingRecorded(null);
    this.dispatchEventToListeners(Profiler.ProfileType.Events.ProfileComplete, profile);
  }

  /**
   * @param {!Common.Event} event
   */
  _addHeapSnapshotChunk(event) {
    if (!this.profileBeingRecorded()) {
      return;
    }
    const chunk = /** @type {string} */ (event.data);
    this.profileBeingRecorded().transferChunk(chunk);
  }

  /**
   * @param {!Common.Event} event
   */
  _reportHeapSnapshotProgress(event) {
    const profile = this.profileBeingRecorded();
    if (!profile) {
      return;
    }
    const data = /** @type {{done: number, total: number, finished: boolean}} */ (event.data);
    profile.updateStatus(Common.UIString('%.0f%%', (data.done / data.total) * 100), true);
    if (data.finished) {
      profile._prepareToLoad();
    }
  }

  /**
   * @param {!Common.Event} event
   */
  _resetProfiles(event) {
    const heapProfilerModel = /** @type {!SDK.HeapProfilerModel} */ (event.data);
    for (const profile of this.getProfiles()) {
      if (profile.heapProfilerModel() === heapProfilerModel) {
        this.removeProfile(profile);
      }
    }
  }

  _snapshotReceived(profile) {
    if (this.profileBeingRecorded() === profile) {
      this.setProfileBeingRecorded(null);
    }
    this.dispatchEventToListeners(Profiler.HeapSnapshotProfileType.SnapshotReceived, profile);
  }
};

Profiler.HeapSnapshotProfileType.TypeId = 'HEAP';
Profiler.HeapSnapshotProfileType.SnapshotReceived = 'SnapshotReceived';

/**
 * @unrestricted
 */
Profiler.TrackingHeapSnapshotProfileType = class extends Profiler.HeapSnapshotProfileType {
  constructor() {
    super(Profiler.TrackingHeapSnapshotProfileType.TypeId, ls`Allocation instrumentation on timeline`);
    this._recordAllocationStacksSetting = Common.settings.createSetting('recordAllocationStacks', false);
    /** @type {?UI.CheckboxLabel} */
    this._customContent = null;
  }

  /**
   * @override
   * @param {!SDK.HeapProfilerModel} heapProfilerModel
   */
  modelAdded(heapProfilerModel) {
    super.modelAdded(heapProfilerModel);
    heapProfilerModel.addEventListener(SDK.HeapProfilerModel.Events.HeapStatsUpdate, this._heapStatsUpdate, this);
    heapProfilerModel.addEventListener(SDK.HeapProfilerModel.Events.LastSeenObjectId, this._lastSeenObjectId, this);
  }

  /**
   * @override
   * @param {!SDK.HeapProfilerModel} heapProfilerModel
   */
  modelRemoved(heapProfilerModel) {
    super.modelRemoved(heapProfilerModel);
    heapProfilerModel.removeEventListener(SDK.HeapProfilerModel.Events.HeapStatsUpdate, this._heapStatsUpdate, this);
    heapProfilerModel.removeEventListener(SDK.HeapProfilerModel.Events.LastSeenObjectId, this._lastSeenObjectId, this);
  }

  /**
   * @param {!Common.Event} event
   */
  _heapStatsUpdate(event) {
    if (!this._profileSamples) {
      return;
    }
    const samples = /** @type {!Array.<number>} */ (event.data);
    let index;
    for (let i = 0; i < samples.length; i += 3) {
      index = samples[i];
      const size = samples[i + 2];
      this._profileSamples.sizes[index] = size;
      if (!this._profileSamples.max[index]) {
        this._profileSamples.max[index] = size;
      }
    }
  }

  /**
   * @param {!Common.Event} event
   */
  _lastSeenObjectId(event) {
    const profileSamples = this._profileSamples;
    if (!profileSamples) {
      return;
    }
    const data = /** @type {{lastSeenObjectId: number, timestamp: number}} */ (event.data);
    const currentIndex = Math.max(profileSamples.ids.length, profileSamples.max.length - 1);
    profileSamples.ids[currentIndex] = data.lastSeenObjectId;
    if (!profileSamples.max[currentIndex]) {
      profileSamples.max[currentIndex] = 0;
      profileSamples.sizes[currentIndex] = 0;
    }
    profileSamples.timestamps[currentIndex] = data.timestamp;
    if (profileSamples.totalTime < data.timestamp - profileSamples.timestamps[0]) {
      profileSamples.totalTime *= 2;
    }
    this.dispatchEventToListeners(Profiler.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._profileSamples);
    this.profileBeingRecorded().updateStatus(null, true);
  }

  /**
   * @override
   * @return {boolean}
   */
  hasTemporaryView() {
    return true;
  }

  /**
   * @override
   */
  get buttonTooltip() {
    return this._recording ? ls`Stop recording heap profile` : ls`Start recording heap profile`;
  }

  /**
   * @override
   * @return {boolean}
   */
  isInstantProfile() {
    return false;
  }

  /**
   * @override
   * @return {boolean}
   */
  buttonClicked() {
    return this._toggleRecording();
  }

  _startRecordingProfile() {
    if (this.profileBeingRecorded()) {
      return;
    }
    const heapProfilerModel = this._addNewProfile();
    if (!heapProfilerModel) {
      return;
    }
    heapProfilerModel.startTrackingHeapObjects(this._recordAllocationStacksSetting.get());
  }

  /**
   * @override
   * @return {?Element}
   */
  customContent() {
    const checkboxSetting = UI.SettingsUI.createSettingCheckbox(
        ls`Record allocation stacks (extra performance overhead)`, this._recordAllocationStacksSetting, true);
    this._customContent = /** @type {!UI.CheckboxLabel} */ (checkboxSetting);
    return checkboxSetting;
  }

  /**
   * @override
   * @param {boolean} enable
   */
  setCustomContentEnabled(enable) {
    this._customContent.checkboxElement.disabled = !enable;
  }

  /**
   * @return {?SDK.HeapProfilerModel}
   */
  _addNewProfile() {
    const heapProfilerModel = UI.context.flavor(SDK.HeapProfilerModel);
    if (!heapProfilerModel) {
      return null;
    }
    this.setProfileBeingRecorded(new Profiler.HeapProfileHeader(heapProfilerModel, this, undefined));
    this._profileSamples = new Profiler.HeapTimelineOverview.Samples();
    this.profileBeingRecorded()._profileSamples = this._profileSamples;
    this._recording = true;
    this.addProfile(/** @type {!Profiler.ProfileHeader} */ (this.profileBeingRecorded()));
    this.profileBeingRecorded().updateStatus(Common.UIString('Recording\u2026'));
    this.dispatchEventToListeners(Profiler.TrackingHeapSnapshotProfileType.TrackingStarted);
    return heapProfilerModel;
  }

  async _stopRecordingProfile() {
    this.profileBeingRecorded().updateStatus(Common.UIString('Snapshotting\u2026'));
    const stopPromise = this.profileBeingRecorded().heapProfilerModel().stopTrackingHeapObjects(true);
    this._recording = false;
    this.dispatchEventToListeners(Profiler.TrackingHeapSnapshotProfileType.TrackingStopped);
    await stopPromise;
    // ------------ ASYNC ------------
    const profile = this.profileBeingRecorded();
    if (!profile) {
      return;
    }
    profile._finishLoad();
    this._profileSamples = null;
    this.setProfileBeingRecorded(null);
    this.dispatchEventToListeners(Profiler.ProfileType.Events.ProfileComplete, profile);
  }

  _toggleRecording() {
    if (this._recording) {
      this._stopRecordingProfile();
    } else {
      this._startRecordingProfile();
    }
    return this._recording;
  }

  /**
   * @override
   * @return {string}
   */
  fileExtension() {
    return '.heaptimeline';
  }

  /**
   * @override
   */
  get treeItemTitle() {
    return ls`ALLOCATION TIMELINES`;
  }

  /**
   * @override
   */
  get description() {
    return ls`
        Allocation timelines show instrumented JavaScript memory allocations over time.
        Once profile is recorded you can select a time interval to see objects that
        were allocated within it and still alive by the end of recording.
        Use this profile type to isolate memory leaks.`;
  }

  /**
   * @override
   * @param {!Common.Event} event
   */
  _resetProfiles(event) {
    const wasRecording = this._recording;
    // Clear current profile to avoid stopping backend.
    this.setProfileBeingRecorded(null);
    super._resetProfiles(event);
    this._profileSamples = null;
    if (wasRecording) {
      this._addNewProfile();
    }
  }

  /**
   * @override
   */
  profileBeingRecordedRemoved() {
    this._stopRecordingProfile();
    this._profileSamples = null;
  }
};

/**
 * @override
 */
Profiler.TrackingHeapSnapshotProfileType.TypeId = 'HEAP-RECORD';

Profiler.TrackingHeapSnapshotProfileType.HeapStatsUpdate = 'HeapStatsUpdate';
Profiler.TrackingHeapSnapshotProfileType.TrackingStarted = 'TrackingStarted';
Profiler.TrackingHeapSnapshotProfileType.TrackingStopped = 'TrackingStopped';

/**
 * @unrestricted
 */
Profiler.HeapProfileHeader = class extends Profiler.ProfileHeader {
  /**
   * @param {?SDK.HeapProfilerModel} heapProfilerModel
   * @param {!Profiler.HeapSnapshotProfileType} type
   * @param {string=} title
   */
  constructor(heapProfilerModel, type, title) {
    super(type, title || Common.UIString('Snapshot %d', type.nextProfileUid()));
    this._heapProfilerModel = heapProfilerModel;
    this.maxJSObjectId = -1;
    /** @type {?Profiler.HeapSnapshotWorkerProxy} */
    this._workerProxy = null;
    /** @type {?Common.OutputStream} */
    this._receiver = null;
    /** @type {?Profiler.HeapSnapshotProxy} */
    this._snapshotProxy = null;
    /** @type {!Promise<!Profiler.HeapSnapshotProxy>} */
    this._loadPromise = new Promise(resolve => this._fulfillLoad = resolve);
    this._totalNumberOfChunks = 0;
    this._bufferedWriter = null;
    /** @type {?Bindings.TempFile} */
    this._tempFile = null;
  }

  /**
   * @return {?SDK.HeapProfilerModel}
   */
  heapProfilerModel() {
    return this._heapProfilerModel;
  }

  /**
   * @param {number} nodeIndex
   * @return {!Promise<?HeapSnapshotModel.Location>}
   */
  getLocation(nodeIndex) {
    return this._snapshotProxy.getLocation(nodeIndex);
  }

  /**
   * @override
   * @param {!Profiler.ProfileType.DataDisplayDelegate} dataDisplayDelegate
   * @return {!Profiler.ProfileSidebarTreeElement}
   */
  createSidebarTreeElement(dataDisplayDelegate) {
    return new Profiler.ProfileSidebarTreeElement(dataDisplayDelegate, this, 'heap-snapshot-sidebar-tree-item');
  }

  /**
   * @override
   * @param {!Profiler.ProfileType.DataDisplayDelegate} dataDisplayDelegate
   * @return {!Profiler.HeapSnapshotView}
   */
  createView(dataDisplayDelegate) {
    return new Profiler.HeapSnapshotView(dataDisplayDelegate, this);
  }

  _prepareToLoad() {
    console.assert(!this._receiver, 'Already loading');
    this._setupWorker();
    this.updateStatus(Common.UIString('Loading\u2026'), true);
  }

  _finishLoad() {
    if (!this._wasDisposed) {
      this._receiver.close();
    }
    if (!this._bufferedWriter) {
      return;
    }
    this._didWriteToTempFile(this._bufferedWriter);
  }

  /**
   * @param {!Bindings.TempFile} tempFile
   */
  _didWriteToTempFile(tempFile) {
    if (this._wasDisposed) {
      if (tempFile) {
        tempFile.remove();
      }
      return;
    }
    this._tempFile = tempFile;
    if (!tempFile) {
      this._failedToCreateTempFile = true;
    }
    if (this._onTempFileReady) {
      this._onTempFileReady();
      this._onTempFileReady = null;
    }
  }

  _setupWorker() {
    /**
     * @this {Profiler.HeapProfileHeader}
     */
    function setProfileWait(event) {
      this.updateStatus(null, event.data);
    }
    console.assert(!this._workerProxy, 'HeapSnapshotWorkerProxy already exists');
    this._workerProxy = new Profiler.HeapSnapshotWorkerProxy(this._handleWorkerEvent.bind(this));
    this._workerProxy.addEventListener(Profiler.HeapSnapshotWorkerProxy.Events.Wait, setProfileWait, this);
    this._receiver = this._workerProxy.createLoader(this.uid, this._snapshotReceived.bind(this));
  }

  /**
   * @param {string} eventName
   * @param {*} data
   */
  _handleWorkerEvent(eventName, data) {
    if (HeapSnapshotModel.HeapSnapshotProgressEvent.BrokenSnapshot === eventName) {
      const error = /** @type {string} */ (data);
      Common.console.error(error);
      return;
    }

    if (HeapSnapshotModel.HeapSnapshotProgressEvent.Update !== eventName) {
      return;
    }
    const serializedMessage = /** @type {string} */ (data);
    const messageObject = Common.deserializeUIString(serializedMessage);
    this.updateStatus(ls(messageObject.messageParts, messageObject.values));
  }

  /**
   * @override
   */
  dispose() {
    if (this._workerProxy) {
      this._workerProxy.dispose();
    }
    this.removeTempFile();
    this._wasDisposed = true;
  }

  _didCompleteSnapshotTransfer() {
    if (!this._snapshotProxy) {
      return;
    }
    this.updateStatus(Number.bytesToString(this._snapshotProxy.totalSize), false);
  }

  /**
   * @param {string} chunk
   */
  transferChunk(chunk) {
    if (!this._bufferedWriter) {
      this._bufferedWriter = new Bindings.TempFile();
    }
    this._bufferedWriter.write([chunk]);

    ++this._totalNumberOfChunks;
    this._receiver.write(chunk);
  }

  _snapshotReceived(snapshotProxy) {
    if (this._wasDisposed) {
      return;
    }
    this._receiver = null;
    this._snapshotProxy = snapshotProxy;
    this.maxJSObjectId = snapshotProxy.maxJSObjectId();
    this._didCompleteSnapshotTransfer();
    this._workerProxy.startCheckingForLongRunningCalls();
    this.notifySnapshotReceived();
  }

  notifySnapshotReceived() {
    this._fulfillLoad(this._snapshotProxy);
    this.profileType()._snapshotReceived(this);
    if (this.canSaveToFile()) {
      this.dispatchEventToListeners(Profiler.ProfileHeader.Events.ProfileReceived);
    }
  }

  /**
   * @override
   * @return {boolean}
   */
  canSaveToFile() {
    return !this.fromFile() && !!this._snapshotProxy;
  }

  /**
   * @override
   */
  saveToFile() {
    const fileOutputStream = new Bindings.FileOutputStream();
    this._fileName = this._fileName || 'Heap-' + new Date().toISO8601Compact() + this.profileType().fileExtension();
    fileOutputStream.open(this._fileName).then(onOpen.bind(this));

    /**
     * @param {boolean} accepted
     * @this {Profiler.HeapProfileHeader}
     */
    async function onOpen(accepted) {
      if (!accepted) {
        return;
      }
      if (this._failedToCreateTempFile) {
        Common.console.error('Failed to open temp file with heap snapshot');
        fileOutputStream.close();
        return;
      }
      if (this._tempFile) {
        const error = await this._tempFile.copyToOutputStream(fileOutputStream, this._onChunkTransferred.bind(this));
        if (error) {
          Common.console.error('Failed to read heap snapshot from temp file: ' + error.message);
        }
        this._didCompleteSnapshotTransfer();
        return;
      }
      this._onTempFileReady = onOpen.bind(this, accepted);
      this._updateSaveProgress(0, 1);
    }
  }

  /**
   * @param {!Bindings.ChunkedReader} reader
   */
  _onChunkTransferred(reader) {
    this._updateSaveProgress(reader.loadedSize(), reader.fileSize());
  }

  /**
   * @param {number} value
   * @param {number} total
   */
  _updateSaveProgress(value, total) {
    const percentValue = ((total && value / total) * 100).toFixed(0);
    this.updateStatus(Common.UIString('Saving\u2026 %d%%', percentValue));
  }

  /**
   * @override
   * @param {!File} file
   * @return {!Promise<?FileError>}
   */
  async loadFromFile(file) {
    this.updateStatus(Common.UIString('Loading\u2026'), true);
    this._setupWorker();
    const reader = new Bindings.ChunkedFileReader(file, 10000000);
    const success = await reader.read(/** @type {!Common.OutputStream} */ (this._receiver));
    if (!success) {
      this.updateStatus(reader.error().message);
    }
    return success ? null : reader.error();
  }
};

/**
 * @unrestricted
 */
Profiler.HeapSnapshotStatisticsView = class extends UI.VBox {
  constructor() {
    super();
    this.element.classList.add('heap-snapshot-statistics-view');
    this._pieChart = new PerfUI.PieChart({
      chartName: ls`Heap memory usage`,
      size: 150,
      formatter: Profiler.HeapSnapshotStatisticsView._valueFormatter,
      showLegend: true
    });
    this._pieChart.element.classList.add('heap-snapshot-stats-pie-chart');
    this.element.appendChild(this._pieChart.element);
  }

  /**
   * @param {number} value
   * @return {string}
   */
  static _valueFormatter(value) {
    return Common.UIString('%s KB', Number.withThousandsSeparator(Math.round(value / 1024)));
  }

  /**
   * @param {number} value
   */
  setTotal(value) {
    this._pieChart.setTotal(value);
  }

  /**
   * @param {number} value
   * @param {string} name
   * @param {string} color
   */
  addRecord(value, name, color) {
    this._pieChart.addSlice(value, color, name);
  }
};

Profiler.HeapAllocationStackView = class extends UI.Widget {
  /**
   * @param {?SDK.HeapProfilerModel} heapProfilerModel
   */
  constructor(heapProfilerModel) {
    super();
    this._heapProfilerModel = heapProfilerModel;
    this._linkifier = new Components.Linkifier();
    /** @type {!Array<!Element>} */
    this._frameElements = [];
  }

  /**
   * @param {!Element} link
   * @param {!Event} event
   */
  _onContextMenu(link, event) {
    const contextMenu = new UI.ContextMenu(event);
    if (!contextMenu.containsTarget(link)) {
      contextMenu.appendApplicableItems(link);
    }
    contextMenu.show();
    event.consume(true);
  }

  /**
   * @param {!Event} event
   */
  _onStackViewKeydown(event) {
    const target = /** @type {?Element} */ (event.target);
    if (!target) {
      return;
    }
    if (isEnterKey(event)) {
      const link = target._linkElement;
      if (!link) {
        return;
      }
      if (Components.Linkifier.invokeFirstAction(link)) {
        event.consume(true);
      }
      return;
    }

    let navDown;
    if (event.key === 'ArrowUp') {
      navDown = false;
    } else if (event.key === 'ArrowDown') {
      navDown = true;
    } else {
      return;
    }

    const index = this._frameElements.indexOf(target);
    if (index === -1) {
      return;
    }
    const nextIndex = navDown ? index + 1 : index - 1;
    if (nextIndex < 0 || nextIndex >= this._frameElements.length) {
      return;
    }

    const nextFrame = this._frameElements[nextIndex];
    nextFrame.tabIndex = 0;
    target.tabIndex = -1;
    nextFrame.focus();
    event.consume(true);
  }

  /**
   * @param {!Profiler.HeapSnapshotProxy} snapshot
   * @param {number} snapshotNodeIndex
   */
  async setAllocatedObject(snapshot, snapshotNodeIndex) {
    this.clear();
    const frames = await snapshot.allocationStack(snapshotNodeIndex);

    if (!frames) {
      const stackDiv = this.element.createChild('div', 'no-heap-allocation-stack');
      stackDiv.createTextChild(Common.UIString(
          'Stack was not recorded for this object because it had been allocated before this profile recording started.'));
      return;
    }

    const stackDiv = this.element.createChild('div', 'heap-allocation-stack');
    stackDiv.addEventListener('keydown', this._onStackViewKeydown.bind(this), false);
    for (const frame of frames) {
      const frameDiv = stackDiv.createChild('div', 'stack-frame');
      this._frameElements.push(frameDiv);
      frameDiv.tabIndex = -1;
      const name = frameDiv.createChild('div');
      name.textContent = UI.beautifyFunctionName(frame.functionName);
      if (!frame.scriptId) {
        continue;
      }
      const urlElement = this._linkifier.linkifyScriptLocation(
          this._heapProfilerModel ? this._heapProfilerModel.target() : null, String(frame.scriptId), frame.scriptName,
          frame.line - 1, frame.column - 1);
      frameDiv.appendChild(urlElement);
      frameDiv._linkElement = urlElement;
      frameDiv.addEventListener('contextmenu', this._onContextMenu.bind(this, urlElement));
    }
    this._frameElements[0].tabIndex = 0;
  }

  clear() {
    this.element.removeChildren();
    this._frameElements = [];
    this._linkifier.reset();
  }
};
