/*
 * Copyright (C) 2012 Google Inc. All rights reserved.
 * Copyright (C) 2012 Intel 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 {Timeline.TimelineController.Client}
 * @implements {Timeline.TimelineModeViewDelegate}
 * @unrestricted
 */
Timeline.TimelinePanel = class extends UI.Panel {
  constructor() {
    super('timeline');
    this.registerRequiredCSS('timeline/timelinePanel.css');
    this.element.addEventListener('contextmenu', this._contextMenu.bind(this), false);
    this._dropTarget = new UI.DropTarget(
        this.element, [UI.DropTarget.Type.File, UI.DropTarget.Type.URI],
        Common.UIString('Drop timeline file or URL here'), this._handleDrop.bind(this));

    /** @type {!Array<!UI.ToolbarItem>} */
    this._recordingOptionUIControls = [];
    this._state = Timeline.TimelinePanel.State.Idle;
    this._recordingPageReload = false;
    this._millisecondsToRecordAfterLoadEvent = 3000;
    this._toggleRecordAction =
        /** @type {!UI.Action }*/ (UI.actionRegistry.action('timeline.toggle-recording'));
    this._recordReloadAction =
        /** @type {!UI.Action }*/ (UI.actionRegistry.action('timeline.record-reload'));

    this._historyManager = new Timeline.TimelineHistoryManager();

    /** @type {?Timeline.PerformanceModel} */
    this._performanceModel = null;

    this._viewModeSetting =
        Common.settings.createSetting('timelineViewMode', Timeline.TimelinePanel.ViewMode.FlameChart);

    this._disableCaptureJSProfileSetting = Common.settings.createSetting('timelineDisableJSSampling', false);
    this._disableCaptureJSProfileSetting.setTitle(Common.UIString('Disable JavaScript samples'));
    this._captureLayersAndPicturesSetting = Common.settings.createSetting('timelineCaptureLayersAndPictures', false);
    this._captureLayersAndPicturesSetting.setTitle(Common.UIString('Enable advanced paint instrumentation (slow)'));

    this._showScreenshotsSetting = Common.settings.createSetting('timelineShowScreenshots', false);
    this._showScreenshotsSetting.setTitle(Common.UIString('Screenshots'));
    this._showScreenshotsSetting.addChangeListener(this._updateOverviewControls, this);

    this._startCoverage = Common.settings.createSetting('timelineStartCoverage', false);
    this._startCoverage.setTitle(ls`Coverage`);

    if (!Root.Runtime.experiments.isEnabled('recordCoverageWithPerformanceTracing')) {
      this._startCoverage.set(false);
    }


    this._showMemorySetting = Common.settings.createSetting('timelineShowMemory', false);
    this._showMemorySetting.setTitle(Common.UIString('Memory'));
    this._showMemorySetting.addChangeListener(this._onModeChanged, this);

    const timelineToolbarContainer = this.element.createChild('div', 'timeline-toolbar-container');
    this._panelToolbar = new UI.Toolbar('timeline-main-toolbar', timelineToolbarContainer);
    this._panelRightToolbar = new UI.Toolbar('', timelineToolbarContainer);
    this._createSettingsPane();
    this._updateShowSettingsToolbarButton();

    this._timelinePane = new UI.VBox();
    this._timelinePane.show(this.element);
    const topPaneElement = this._timelinePane.element.createChild('div', 'hbox');
    topPaneElement.id = 'timeline-overview-panel';

    // Create top overview component.
    this._overviewPane = new PerfUI.TimelineOverviewPane('timeline');
    this._overviewPane.addEventListener(
        PerfUI.TimelineOverviewPane.Events.WindowChanged, this._onOverviewWindowChanged.bind(this));
    this._overviewPane.show(topPaneElement);
    /** @type {!Array<!Timeline.TimelineEventOverview>} */
    this._overviewControls = [];

    this._statusPaneContainer = this._timelinePane.element.createChild('div', 'status-pane-container fill');

    this._createFileSelector();

    SDK.targetManager.addModelListener(
        SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.Load, this._loadEventFired, this);

    this._flameChart = new Timeline.TimelineFlameChartView(this);
    this._searchableView = new UI.SearchableView(this._flameChart);
    this._searchableView.setMinimumSize(0, 100);
    this._searchableView.element.classList.add('searchable-view');
    this._searchableView.show(this._timelinePane.element);
    this._flameChart.show(this._searchableView.element);
    this._flameChart.setSearchableView(this._searchableView);

    this._onModeChanged();
    this._populateToolbar();
    this._showLandingPage();
    this._updateTimelineControls();

    Extensions.extensionServer.addEventListener(
        Extensions.ExtensionServer.Events.TraceProviderAdded, this._appendExtensionsToToolbar, this);
    SDK.targetManager.addEventListener(SDK.TargetManager.Events.SuspendStateChanged, this._onSuspendStateChanged, this);
  }

  /**
   * @return {!Timeline.TimelinePanel}
   */
  static instance() {
    return /** @type {!Timeline.TimelinePanel} */ (self.runtime.sharedInstance(Timeline.TimelinePanel));
  }

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

  /**
   * @override
   */
  wasShown() {
    UI.context.setFlavor(Timeline.TimelinePanel, this);
  }

  /**
   * @override
   */
  willHide() {
    UI.context.setFlavor(Timeline.TimelinePanel, null);
    this._historyManager.cancelIfShowing();
  }

  /**
   * @param {!Array.<!SDK.TracingManager.EventPayload>} events
   */
  loadFromEvents(events) {
    if (this._state !== Timeline.TimelinePanel.State.Idle) {
      return;
    }
    this._prepareToLoadTimeline();
    this._loader = Timeline.TimelineLoader.loadFromEvents(events, this);
  }

  /**
   * @param {!Common.Event} event
   */
  _onOverviewWindowChanged(event) {
    const left = event.data.startTime;
    const right = event.data.endTime;
    this._performanceModel.setWindow({left, right}, /* animate */ true);
  }

  /**
   * @param {!Common.Event} event
   */
  _onModelWindowChanged(event) {
    const window = /** @type {!Timeline.PerformanceModel.Window} */ (event.data.window);
    this._overviewPane.setWindowTimes(window.left, window.right);
  }

  /**
   * @param {!Timeline.TimelinePanel.State} state
   */
  _setState(state) {
    this._state = state;
    this._updateTimelineControls();
  }

  /**
   * @param {!Common.Setting} setting
   * @param {string} tooltip
   * @return {!UI.ToolbarItem}
   */
  _createSettingCheckbox(setting, tooltip) {
    const checkboxItem = new UI.ToolbarSettingCheckbox(setting, tooltip);
    this._recordingOptionUIControls.push(checkboxItem);
    return checkboxItem;
  }

  _populateToolbar() {
    // Record
    this._panelToolbar.appendToolbarItem(UI.Toolbar.createActionButton(this._toggleRecordAction));
    this._panelToolbar.appendToolbarItem(UI.Toolbar.createActionButton(this._recordReloadAction));
    this._clearButton = new UI.ToolbarButton(Common.UIString('Clear'), 'largeicon-clear');
    this._clearButton.addEventListener(UI.ToolbarButton.Events.Click, () => this._onClearButton());
    this._panelToolbar.appendToolbarItem(this._clearButton);

    // Load / Save
    this._loadButton = new UI.ToolbarButton(Common.UIString('Load profile...'), 'largeicon-load');
    this._loadButton.addEventListener(UI.ToolbarButton.Events.Click, () => this._selectFileToLoad());
    this._saveButton = new UI.ToolbarButton(Common.UIString('Save profile...'), 'largeicon-download');
    this._saveButton.addEventListener(UI.ToolbarButton.Events.Click, () => this._saveToFile());
    this._panelToolbar.appendSeparator();
    this._panelToolbar.appendToolbarItem(this._loadButton);
    this._panelToolbar.appendToolbarItem(this._saveButton);

    // History
    this._panelToolbar.appendSeparator();
    this._panelToolbar.appendToolbarItem(this._historyManager.button());
    this._panelToolbar.appendSeparator();

    // View
    // this._panelToolbar.appendSeparator();
    // this._showScreenshotsToolbarCheckbox =
    //     this._createSettingCheckbox(this._showScreenshotsSetting, Common.UIString('Capture screenshots'));
    // this._panelToolbar.appendToolbarItem(this._showScreenshotsToolbarCheckbox);

    // this._showMemoryToolbarCheckbox =
    //     this._createSettingCheckbox(this._showMemorySetting, Common.UIString('Show memory timeline'));
    // this._panelToolbar.appendToolbarItem(this._showMemoryToolbarCheckbox);

    if (Root.Runtime.experiments.isEnabled('recordCoverageWithPerformanceTracing')) {
      this._startCoverageCheckbox =
          this._createSettingCheckbox(this._startCoverage, ls`Record coverage with performance trace`);
      this._panelToolbar.appendToolbarItem(this._startCoverageCheckbox);
    }

    // GC
    // this._panelToolbar.appendToolbarItem(UI.Toolbar.createActionButtonForId('components.collect-garbage'));

    // Settings
    // this._panelRightToolbar.appendSeparator();
    // this._panelRightToolbar.appendToolbarItem(this._showSettingsPaneButton);
  }

  _createSettingsPane() {
    this._showSettingsPaneSetting = Common.settings.createSetting('timelineShowSettingsToolbar', false);
    this._showSettingsPaneButton = new UI.ToolbarSettingToggle(
        this._showSettingsPaneSetting, 'largeicon-settings-gear', Common.UIString('Capture settings'));
    SDK.multitargetNetworkManager.addEventListener(
        SDK.MultitargetNetworkManager.Events.ConditionsChanged, this._updateShowSettingsToolbarButton, this);
    MobileThrottling.throttlingManager().addEventListener(
        MobileThrottling.ThrottlingManager.Events.RateChanged, this._updateShowSettingsToolbarButton, this);
    this._disableCaptureJSProfileSetting.addChangeListener(this._updateShowSettingsToolbarButton, this);
    this._captureLayersAndPicturesSetting.addChangeListener(this._updateShowSettingsToolbarButton, this);

    this._settingsPane = new UI.HBox();
    this._settingsPane.element.classList.add('timeline-settings-pane');
    this._settingsPane.show(this.element);

    const captureToolbar = new UI.Toolbar('', this._settingsPane.element);
    captureToolbar.element.classList.add('flex-auto');
    captureToolbar.makeVertical();
    captureToolbar.appendToolbarItem(this._createSettingCheckbox(
        this._disableCaptureJSProfileSetting,
        Common.UIString('Disables JavaScript sampling, reduces overhead when running against mobile devices')));
    captureToolbar.appendToolbarItem(this._createSettingCheckbox(
        this._captureLayersAndPicturesSetting,
        Common.UIString('Captures advanced paint instrumentation, introduces significant performance overhead')));

    const throttlingPane = new UI.VBox();
    throttlingPane.element.classList.add('flex-auto');
    throttlingPane.show(this._settingsPane.element);

    const networkThrottlingToolbar = new UI.Toolbar('', throttlingPane.element);
    networkThrottlingToolbar.appendText(Common.UIString('Network:'));
    this._networkThrottlingSelect = this._createNetworkConditionsSelect();
    networkThrottlingToolbar.appendToolbarItem(this._networkThrottlingSelect);

    const cpuThrottlingToolbar = new UI.Toolbar('', throttlingPane.element);
    cpuThrottlingToolbar.appendText(Common.UIString('CPU:'));
    this._cpuThrottlingSelect = MobileThrottling.throttlingManager().createCPUThrottlingSelector();
    cpuThrottlingToolbar.appendToolbarItem(this._cpuThrottlingSelect);

    this._showSettingsPaneSetting.addChangeListener(this._updateSettingsPaneVisibility.bind(this));
    this._updateSettingsPaneVisibility();
  }

  /**
    * @param {!Common.Event} event
    */
  _appendExtensionsToToolbar(event) {
    const provider = /** @type {!Extensions.ExtensionTraceProvider} */ (event.data);
    const setting = Timeline.TimelinePanel._settingForTraceProvider(provider);
    const checkbox = this._createSettingCheckbox(setting, provider.longDisplayName());
    this._panelToolbar.appendToolbarItem(checkbox);
  }

  /**
   * @param {!Extensions.ExtensionTraceProvider} traceProvider
   * @return {!Common.Setting<boolean>}
   */
  static _settingForTraceProvider(traceProvider) {
    let setting = traceProvider[Timeline.TimelinePanel._traceProviderSettingSymbol];
    if (!setting) {
      const providerId = traceProvider.persistentIdentifier();
      setting = Common.settings.createSetting(providerId, false);
      setting.setTitle(traceProvider.shortDisplayName());
      traceProvider[Timeline.TimelinePanel._traceProviderSettingSymbol] = setting;
    }
    return setting;
  }

  /**
   * @return {!UI.ToolbarComboBox}
   */
  _createNetworkConditionsSelect() {
    const toolbarItem = new UI.ToolbarComboBox(null, ls`Network conditions`);
    toolbarItem.setMaxWidth(140);
    MobileThrottling.throttlingManager().decorateSelectWithNetworkThrottling(toolbarItem.selectElement());
    return toolbarItem;
  }

  _prepareToLoadTimeline() {
    console.assert(this._state === Timeline.TimelinePanel.State.Idle);
    this._setState(Timeline.TimelinePanel.State.Loading);
    if (this._performanceModel) {
      this._performanceModel.dispose();
      this._performanceModel = null;
    }
  }

  _createFileSelector() {
    if (this._fileSelectorElement) {
      this._fileSelectorElement.remove();
    }
    this._fileSelectorElement = UI.createFileSelectorElement(this._loadFromFile.bind(this));
    this._timelinePane.element.appendChild(this._fileSelectorElement);
  }

  /**
   * @param {!Event} event
   */
  _contextMenu(event) {
    const contextMenu = new UI.ContextMenu(event);
    contextMenu.appendItemsAtLocation('timelineMenu');
    contextMenu.show();
  }

  /**
   * @suppress {deprecated}
   */
  async _saveToFile() {
    if (this._state !== Timeline.TimelinePanel.State.Idle) {
      return;
    }
    const performanceModel = this._performanceModel;
    if (!performanceModel) {
      return;
    }

    const now = new Date();
    const fileName = 'Profile-' + now.toISO8601Compact() + '.json';
    const stream = new Bindings.FileOutputStream();

    const accepted = await stream.open(fileName);
    if (!accepted) {
      return;
    }

    const error = await performanceModel.save(stream);
    if (!error) {
      return;
    }
    Common.console.error(
        Common.UIString('Failed to save timeline: %s (%s, %s)', error.message, error.name, error.code));
  }

  async _showHistory() {
    const model = await this._historyManager.showHistoryDropDown();
    if (model && model !== this._performanceModel) {
      this._setModel(model);
    }
  }

  /**
   * @param {number} direction
   * @return {boolean}
   */
  _navigateHistory(direction) {
    const model = this._historyManager.navigate(direction);
    if (model && model !== this._performanceModel) {
      this._setModel(model);
    }
    return true;
  }

  _selectFileToLoad() {
    this._fileSelectorElement.click();
  }

  /**
   * @param {!File} file
   */
  _loadFromFile(file) {
    if (this._state !== Timeline.TimelinePanel.State.Idle) {
      return;
    }
    this._prepareToLoadTimeline();
    this._loader = Timeline.TimelineLoader.loadFromFile(file, this);
    this._createFileSelector();
  }

  /**
   * @param {string} url
   */
  _loadFromURL(url) {
    if (this._state !== Timeline.TimelinePanel.State.Idle) {
      return;
    }
    this._prepareToLoadTimeline();
    this._loader = Timeline.TimelineLoader.loadFromURL(url, this);
  }

  _updateOverviewControls() {
    this._overviewControls = [];
    this._overviewControls.push(new Timeline.TimelineEventOverviewResponsiveness());
    if (Root.Runtime.experiments.isEnabled('inputEventsOnTimelineOverview')) {
      this._overviewControls.push(new Timeline.TimelineEventOverviewInput());
    }
    this._overviewControls.push(new Timeline.TimelineEventOverviewFrames());
    this._overviewControls.push(new Timeline.TimelineEventOverviewCPUActivity());
    this._overviewControls.push(new Timeline.TimelineEventOverviewNetwork());
    if (this._showScreenshotsSetting.get() && this._performanceModel &&
        this._performanceModel.filmStripModel().frames().length) {
      this._overviewControls.push(new Timeline.TimelineFilmStripOverview());
    }
    if (this._showMemorySetting.get()) {
      this._overviewControls.push(new Timeline.TimelineEventOverviewMemory());
    }
    if (this._startCoverage.get()) {
      this._overviewControls.push(new Timeline.TimelineEventOverviewCoverage());
    }
    for (const control of this._overviewControls) {
      control.setModel(this._performanceModel);
    }
    this._overviewPane.setOverviewControls(this._overviewControls);
  }

  _onModeChanged() {
    this._updateOverviewControls();
    this.doResize();
    this.select(null);
  }

  _updateSettingsPaneVisibility() {
    if (this._showSettingsPaneSetting.get()) {
      this._settingsPane.showWidget();
    } else {
      this._settingsPane.hideWidget();
    }
  }

  _updateShowSettingsToolbarButton() {
    const messages = [];
    if (MobileThrottling.throttlingManager().cpuThrottlingRate() !== 1) {
      messages.push(Common.UIString('- CPU throttling is enabled'));
    }
    if (SDK.multitargetNetworkManager.isThrottling()) {
      messages.push(Common.UIString('- Network throttling is enabled'));
    }
    if (this._captureLayersAndPicturesSetting.get()) {
      messages.push(Common.UIString('- Significant overhead due to paint instrumentation'));
    }
    if (this._disableCaptureJSProfileSetting.get()) {
      messages.push(Common.UIString('- JavaScript sampling is disabled'));
    }

    this._showSettingsPaneButton.setDefaultWithRedColor(messages.length);
    this._showSettingsPaneButton.setToggleWithRedColor(messages.length);

    if (messages.length) {
      const tooltipElement = createElement('div');
      messages.forEach(message => {
        tooltipElement.createChild('div').textContent = message;
      });
      this._showSettingsPaneButton.setTitle(tooltipElement);
    } else {
      this._showSettingsPaneButton.setTitle(Common.UIString('Capture settings'));
    }
  }

  /**
   * @param {boolean} enabled
   */
  _setUIControlsEnabled(enabled) {
    this._recordingOptionUIControls.forEach(control => control.setEnabled(enabled));
  }

  async _startRecording() {
    console.assert(!this._statusPane, 'Status pane is already opened.');
    this._setState(Timeline.TimelinePanel.State.StartPending);

    const recordingOptions = {
      enableJSSampling: !this._disableCaptureJSProfileSetting.get(),
      capturePictures: this._captureLayersAndPicturesSetting.get(),
      captureFilmStrip: this._showScreenshotsSetting.get(),
      startCoverage: this._startCoverage.get()
    };

    if (recordingOptions.startCoverage) {
      await UI.viewManager.showView('coverage')
          .then(() => UI.viewManager.view('coverage').widget())
          .then(widget => widget.ensureRecordingStarted());
    }

    this._showRecordingStarted();

    const enabledTraceProviders = Extensions.extensionServer.traceProviders().filter(
        provider => Timeline.TimelinePanel._settingForTraceProvider(provider).get());

    const mainTarget = /** @type {!SDK.Target} */ (SDK.targetManager.mainTarget());
    if (Timeline.UIDevtoolsUtils.isUiDevTools()) {
      this._controller = new Timeline.UIDevtoolsController(mainTarget, this);
    } else {
      this._controller = new Timeline.TimelineController(mainTarget, this);
    }
    this._setUIControlsEnabled(false);
    this._hideLandingPage();
    const response = await this._controller.startRecording(recordingOptions, enabledTraceProviders);
    if (response[Protocol.Error]) {
      this._recordingFailed(response[Protocol.Error]);
    } else {
      this._recordingStarted();
    }
  }

  async _stopRecording() {
    if (this._statusPane) {
      this._statusPane.finish();
      this._statusPane.updateStatus(Common.UIString('Stopping timeline\u2026'));
      this._statusPane.updateProgressBar(Common.UIString('Received'), 0);
    }
    this._setState(Timeline.TimelinePanel.State.StopPending);
    const model = await this._controller.stopRecording();
    this._performanceModel = model;
    this._setUIControlsEnabled(true);
    this._controller.dispose();
    this._controller = null;
  }

  /**
   * @param {string} error The error message to display
   */
  _recordingFailed(error) {
    if (this._statusPane) {
      this._statusPane.hide();
    }
    this._statusPane = new Timeline.TimelinePanel.StatusPane({description: error}, () => this.loadingComplete(null));
    this._statusPane.showPane(this._statusPaneContainer);
    this._statusPane.updateStatus(ls`Recording failed`);
    this._statusPane.updateButton(ls`Close`);

    this._setState(Timeline.TimelinePanel.State.RecordingFailed);
    this._performanceModel = null;
    this._setUIControlsEnabled(false);
    this._controller.dispose();
    this._controller = null;
  }

  _onSuspendStateChanged() {
    this._updateTimelineControls();
  }

  _updateTimelineControls() {
    const state = Timeline.TimelinePanel.State;
    this._toggleRecordAction.setToggled(this._state === state.Recording);
    this._toggleRecordAction.setEnabled(this._state === state.Recording || this._state === state.Idle);
    this._recordReloadAction.setEnabled(this._state === state.Idle);
    this._historyManager.setEnabled(this._state === state.Idle);
    this._clearButton.setEnabled(this._state === state.Idle);
    this._panelToolbar.setEnabled(this._state !== state.Loading);
    this._panelRightToolbar.setEnabled(this._state !== state.Loading);
    this._dropTarget.setEnabled(this._state === state.Idle);
    this._loadButton.setEnabled(this._state === state.Idle);
    this._saveButton.setEnabled(this._state === state.Idle && !!this._performanceModel);
  }

  _toggleRecording() {
    if (this._state === Timeline.TimelinePanel.State.Idle) {
      this._recordingPageReload = false;
      this._startRecording();
      Host.userMetrics.actionTaken(Host.UserMetrics.Action.TimelineStarted);
    } else if (this._state === Timeline.TimelinePanel.State.Recording) {
      this._stopRecording();
    }
  }

  _recordReload() {
    if (this._state !== Timeline.TimelinePanel.State.Idle) {
      return;
    }
    this._recordingPageReload = true;
    this._startRecording();
    Host.userMetrics.actionTaken(Host.UserMetrics.Action.TimelinePageReloadStarted);
  }

  _onClearButton() {
    this._historyManager.clear();
    this._clear();
  }

  _clear() {
    this._showLandingPage();
    this._reset();
  }

  _reset() {
    self.runtime.sharedInstance(PerfUI.LineLevelProfile.Performance).reset();
    this._setModel(null);
  }

  /**
   * @param {!Timeline.PerformanceModel} model
   */
  _applyFilters(model) {
    if (model.timelineModel().isGenericTrace() || Root.Runtime.experiments.isEnabled('timelineShowAllEvents')) {
      return;
    }
    model.setFilters([Timeline.TimelineUIUtils.visibleEventsFilter()]);
  }

  /**
   * @param {?Timeline.PerformanceModel} model
   */
  _setModel(model) {
    if (this._performanceModel) {
      this._performanceModel.removeEventListener(
          Timeline.PerformanceModel.Events.WindowChanged, this._onModelWindowChanged, this);
    }
    this._performanceModel = model;
    if (model) {
      this._applyFilters(model);
    }
    this._flameChart.setModel(model);

    this._updateOverviewControls();
    this._overviewPane.reset();
    if (model) {
      this._performanceModel.addEventListener(
          Timeline.PerformanceModel.Events.WindowChanged, this._onModelWindowChanged, this);
      this._overviewPane.setBounds(
          model.timelineModel().minimumRecordTime(), model.timelineModel().maximumRecordTime());
      const lineLevelProfile = self.runtime.sharedInstance(PerfUI.LineLevelProfile.Performance);
      lineLevelProfile.reset();
      for (const profile of model.timelineModel().cpuProfiles()) {
        lineLevelProfile.appendCPUProfile(profile);
      }
      this._setMarkers(model.timelineModel());
      this._flameChart.setSelection(null);
      this._overviewPane.setWindowTimes(model.window().left, model.window().right);
    }
    for (const control of this._overviewControls) {
      control.setModel(model);
    }
    if (this._flameChart) {
      this._flameChart.resizeToPreferredHeights();
    }
    this._updateTimelineControls();
  }

  _recordingStarted() {
    if (this._recordingPageReload) {
      const target = this._controller.mainTarget();
      const resourceModel = target.model(SDK.ResourceTreeModel);
      if (resourceModel) {
        resourceModel.reloadPage();
      }
    }
    this._reset();
    this._setState(Timeline.TimelinePanel.State.Recording);
    this._showRecordingStarted();
    this._statusPane.updateStatus(Common.UIString('Profiling\u2026'));
    this._statusPane.updateProgressBar(Common.UIString('Buffer usage'), 0);
    this._statusPane.startTimer();
    this._hideLandingPage();
  }

  /**
   * @override
   * @param {number} usage
   */
  recordingProgress(usage) {
    this._statusPane.updateProgressBar(Common.UIString('Buffer usage'), usage * 100);
  }

  _showLandingPage() {
    if (this._landingPage) {
      this._landingPage.show(this._statusPaneContainer);
      return;
    }

    /**
     * @param {string} tagName
     * @param {string} contents
     */
    function encloseWithTag(tagName, contents) {
      const e = createElement(tagName);
      e.textContent = contents;
      return e;
    }

    const learnMoreNode = UI.XLink.create(
        'https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/',
        Common.UIString('Learn\xa0more'));

    const recordKey =
        encloseWithTag('b', UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.toggle-recording')[0].name);
    const reloadKey =
        encloseWithTag('b', UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.record-reload')[0].name);
    const navigateNode = encloseWithTag('b', Common.UIString('WASD'));

    this._landingPage = new UI.VBox();
    this._landingPage.contentElement.classList.add('timeline-landing-page', 'fill');
    const centered = this._landingPage.contentElement.createChild('div');

    const recordButton = UI.createInlineButton(UI.Toolbar.createActionButton(this._toggleRecordAction));
    const reloadButton = UI.createInlineButton(UI.Toolbar.createActionButtonForId('timeline.record-reload'));

    centered.createChild('p').appendChild(UI.formatLocalized(
        'Click the record button %s or hit %s to start a new recording.\nClick the reload button %s or hit %s to record the page load.',
        [recordButton, recordKey, reloadButton, reloadKey]));

    centered.createChild('p').appendChild(UI.formatLocalized(
        'After recording, select an area of interest in the overview by dragging.\nThen, zoom and pan the timeline with the mousewheel or %s keys.\n%s',
        [navigateNode, learnMoreNode]));

    this._landingPage.show(this._statusPaneContainer);
  }

  _hideLandingPage() {
    this._landingPage.detach();
  }

  /**
   * @override
   */
  loadingStarted() {
    this._hideLandingPage();

    if (this._statusPane) {
      this._statusPane.hide();
    }
    this._statusPane = new Timeline.TimelinePanel.StatusPane({showProgress: true}, this._cancelLoading.bind(this));
    this._statusPane.showPane(this._statusPaneContainer);
    this._statusPane.updateStatus(Common.UIString('Loading profile\u2026'));
    // FIXME: make loading from backend cancelable as well.
    if (!this._loader) {
      this._statusPane.finish();
    }
    this.loadingProgress(0);
  }

  /**
   * @override
   * @param {number=} progress
   */
  loadingProgress(progress) {
    if (typeof progress === 'number') {
      this._statusPane.updateProgressBar(Common.UIString('Received'), progress * 100);
    }
  }

  /**
   * @override
   */
  processingStarted() {
    this._statusPane.updateStatus(Common.UIString('Processing profile\u2026'));
  }

  /**
   * @override
   * @param {?SDK.TracingModel} tracingModel
   */
  loadingComplete(tracingModel) {
    delete this._loader;
    this._setState(Timeline.TimelinePanel.State.Idle);

    if (this._statusPane) {
      this._statusPane.hide();
    }
    delete this._statusPane;

    if (!tracingModel) {
      this._clear();
      return;
    }

    if (!this._performanceModel) {
      this._performanceModel = new Timeline.PerformanceModel();
    }
    this._performanceModel.setTracingModel(tracingModel);
    this._setModel(this._performanceModel);
    this._historyManager.addRecording(this._performanceModel);

    if (this._startCoverage.get()) {
      UI.viewManager.showView('coverage')
          .then(() => UI.viewManager.view('coverage').widget())
          .then(widget => widget.stopRecording())
          .then(() => this._updateOverviewControls());
    }
  }

  _showRecordingStarted() {
    if (this._statusPane) {
      return;
    }
    this._statusPane =
        new Timeline.TimelinePanel.StatusPane({showTimer: true, showProgress: true}, this._stopRecording.bind(this));
    this._statusPane.showPane(this._statusPaneContainer);
    this._statusPane.updateStatus(Common.UIString('Initializing profiler\u2026'));
  }

  _cancelLoading() {
    if (this._loader) {
      this._loader.cancel();
    }
  }

  /**
   * @param {!TimelineModel.TimelineModel} timelineModel
   */
  _setMarkers(timelineModel) {
    const markers = new Map();
    const recordTypes = TimelineModel.TimelineModel.RecordType;
    const zeroTime = timelineModel.minimumRecordTime();
    for (const event of timelineModel.timeMarkerEvents()) {
      if (event.name === recordTypes.TimeStamp || event.name === recordTypes.ConsoleTime) {
        continue;
      }
      markers.set(event.startTime, Timeline.TimelineUIUtils.createEventDivider(event, zeroTime));
    }
    this._overviewPane.setMarkers(markers);
  }

  /**
   * @param {!Common.Event} event
   */
  async _loadEventFired(event) {
    if (this._state !== Timeline.TimelinePanel.State.Recording || !this._recordingPageReload ||
        this._controller.mainTarget() !== event.data.resourceTreeModel.target()) {
      return;
    }
    const controller = this._controller;
    await new Promise(r => setTimeout(r, this._millisecondsToRecordAfterLoadEvent));

    // Check if we're still in the same recording session.
    if (controller !== this._controller || this._state !== Timeline.TimelinePanel.State.Recording) {
      return;
    }
    this._stopRecording();
  }

  /**
   * @param {!Timeline.TimelineSelection} selection
   * @return {?TimelineModel.TimelineFrame}
   */
  _frameForSelection(selection) {
    switch (selection.type()) {
      case Timeline.TimelineSelection.Type.Frame:
        return /** @type {!TimelineModel.TimelineFrame} */ (selection.object());
      case Timeline.TimelineSelection.Type.Range:
        return null;
      case Timeline.TimelineSelection.Type.TraceEvent:
        return this._performanceModel.frameModel().frames(selection._endTime, selection._endTime)[0];
      default:
        console.assert(false, 'Should never be reached');
        return null;
    }
  }

  /**
   * @param {number} offset
   */
  _jumpToFrame(offset) {
    const currentFrame = this._selection && this._frameForSelection(this._selection);
    if (!currentFrame) {
      return;
    }
    const frames = this._performanceModel.frames();
    let index = frames.indexOf(currentFrame);
    console.assert(index >= 0, 'Can\'t find current frame in the frame list');
    index = Number.constrain(index + offset, 0, frames.length - 1);
    const frame = frames[index];
    this._revealTimeRange(frame.startTime, frame.endTime);
    this.select(Timeline.TimelineSelection.fromFrame(frame));
    return true;
  }

  /**
   * @override
   * @param {?Timeline.TimelineSelection} selection
   */
  select(selection) {
    this._selection = selection;
    this._flameChart.setSelection(selection);
  }

  /**
   * @override
   * @param {?Array<!SDK.TracingModel.Event>} events
   * @param {number} time
   */
  selectEntryAtTime(events, time) {
    if (!events) {
      return;
    }
    // Find best match, then backtrack to the first visible entry.
    for (let index = events.upperBound(time, (time, event) => time - event.startTime) - 1; index >= 0; --index) {
      const event = events[index];
      const endTime = event.endTime || event.startTime;
      if (SDK.TracingModel.isTopLevelEvent(event) && endTime < time) {
        break;
      }
      if (this._performanceModel.isVisible(event) && endTime >= time) {
        this.select(Timeline.TimelineSelection.fromTraceEvent(event));
        return;
      }
    }
    this.select(null);
  }

  /**
   * @override
   * @param {?SDK.TracingModel.Event} event
   */
  highlightEvent(event) {
    this._flameChart.highlightEvent(event);
  }

  /**
   * @param {number} startTime
   * @param {number} endTime
   */
  _revealTimeRange(startTime, endTime) {
    const window = this._performanceModel.window();
    let offset = 0;
    if (window.right < endTime) {
      offset = endTime - window.right;
    } else if (window.left > startTime) {
      offset = startTime - window.left;
    }
    this._performanceModel.setWindow({left: window.left + offset, right: window.right + offset}, /* animate */ true);
  }

  /**
   * @param {!DataTransfer} dataTransfer
   */
  _handleDrop(dataTransfer) {
    const items = dataTransfer.items;
    if (!items.length) {
      return;
    }
    const item = items[0];
    if (item.kind === 'string') {
      const url = dataTransfer.getData('text/uri-list');
      if (new Common.ParsedURL(url).isValid) {
        this._loadFromURL(url);
      }
    } else if (item.kind === 'file') {
      const entry = items[0].webkitGetAsEntry();
      if (!entry.isFile) {
        return;
      }
      entry.file(this._loadFromFile.bind(this));
    }
  }
};

/**
 * @enum {symbol}
 */
Timeline.TimelinePanel.State = {
  Idle: Symbol('Idle'),
  StartPending: Symbol('StartPending'),
  Recording: Symbol('Recording'),
  StopPending: Symbol('StopPending'),
  Loading: Symbol('Loading'),
  RecordingFailed: Symbol('RecordingFailed')
};

/**
 * @enum {string}
 */
Timeline.TimelinePanel.ViewMode = {
  FlameChart: 'FlameChart',
  BottomUp: 'BottomUp',
  CallTree: 'CallTree',
  EventLog: 'EventLog'
};

// Define row and header height, should be in sync with styles for timeline graphs.
Timeline.TimelinePanel.rowHeight = 18;
Timeline.TimelinePanel.headerHeight = 20;

/** @typedef {{selection: ?Timeline.TimelineSelection, windowLeftTime: number, windowRightTime: number}} */
Timeline.TimelinePanel.ModelSelectionData;

Timeline.TimelineSelection = class {
  /**
   * @param {!Timeline.TimelineSelection.Type} type
   * @param {number} startTime
   * @param {number} endTime
   * @param {!Object=} object
   */
  constructor(type, startTime, endTime, object) {
    this._type = type;
    this._startTime = startTime;
    this._endTime = endTime;
    this._object = object || null;
  }

  /**
   * @param {!TimelineModel.TimelineFrame} frame
   * @return {!Timeline.TimelineSelection}
   */
  static fromFrame(frame) {
    return new Timeline.TimelineSelection(Timeline.TimelineSelection.Type.Frame, frame.startTime, frame.endTime, frame);
  }

  /**
   * @param {!TimelineModel.TimelineModel.NetworkRequest} request
   * @return {!Timeline.TimelineSelection}
   */
  static fromNetworkRequest(request) {
    return new Timeline.TimelineSelection(
        Timeline.TimelineSelection.Type.NetworkRequest, request.startTime, request.endTime || request.startTime,
        request);
  }

  /**
   * @param {!SDK.TracingModel.Event} event
   * @return {!Timeline.TimelineSelection}
   */
  static fromTraceEvent(event) {
    return new Timeline.TimelineSelection(
        Timeline.TimelineSelection.Type.TraceEvent, event.startTime, event.endTime || (event.startTime + 1), event);
  }

  /**
   * @param {number} startTime
   * @param {number} endTime
   * @return {!Timeline.TimelineSelection}
   */
  static fromRange(startTime, endTime) {
    return new Timeline.TimelineSelection(Timeline.TimelineSelection.Type.Range, startTime, endTime);
  }

  /**
   * @return {!Timeline.TimelineSelection.Type}
   */
  type() {
    return this._type;
  }

  /**
   * @return {?Object}
   */
  object() {
    return this._object;
  }

  /**
   * @return {number}
   */
  startTime() {
    return this._startTime;
  }

  /**
   * @return {number}
   */
  endTime() {
    return this._endTime;
  }
};

/**
 * @enum {string}
 */
Timeline.TimelineSelection.Type = {
  Frame: 'Frame',
  NetworkRequest: 'NetworkRequest',
  TraceEvent: 'TraceEvent',
  Range: 'Range'
};

/**
 * @interface
 */
Timeline.TimelineModeViewDelegate = function() {};

Timeline.TimelineModeViewDelegate.prototype = {
  /**
   * @param {?Timeline.TimelineSelection} selection
   */
  select(selection) {},

  /**
   * @param {?Array<!SDK.TracingModel.Event>} events
   * @param {number} time
   */
  selectEntryAtTime(events, time) {},

  /**
   * @param {?SDK.TracingModel.Event} event
   */
  highlightEvent(event) {},
};

/**
 * @unrestricted
 */
Timeline.TimelinePanel.StatusPane = class extends UI.VBox {
  /**
   * @param {!{showTimer: (boolean|undefined), showProgress: (boolean|undefined), description: (string|undefined)}} options - a collection of options controlling the appearance of the pane.
   *   The options object can have the following properties:
   *   - **showTimer** - `{boolean}` - Display seconds since dialog opened
   *   - **showProgress** - `{boolean}` - Display a progress bar
   *   - **description** - `{string}` - Display this string in a description line
   * @param {function()} stopCallback
   */
  constructor(options, stopCallback) {
    super(true);
    this.registerRequiredCSS('timeline/timelineStatusDialog.css');
    this.contentElement.classList.add('timeline-status-dialog');

    const statusLine = this.contentElement.createChild('div', 'status-dialog-line status');
    statusLine.createChild('div', 'label').textContent = Common.UIString('Status');
    this._status = statusLine.createChild('div', 'content');
    UI.ARIAUtils.markAsStatus(this._status);

    if (options.showTimer) {
      const timeLine = this.contentElement.createChild('div', 'status-dialog-line time');
      timeLine.createChild('div', 'label').textContent = Common.UIString('Time');
      this._time = timeLine.createChild('div', 'content');
    }

    if (options.showProgress) {
      const progressLine = this.contentElement.createChild('div', 'status-dialog-line progress');
      this._progressLabel = progressLine.createChild('div', 'label');
      this._progressBar = progressLine.createChild('div', 'indicator-container').createChild('div', 'indicator');
      UI.ARIAUtils.markAsProgressBar(this._progressBar);
    }

    if (typeof options.description === 'string') {
      const descriptionLine = this.contentElement.createChild('div', 'status-dialog-line description');
      descriptionLine.createChild('div', 'label').textContent = ls`Description`;
      this._description = descriptionLine.createChild('div', 'content');
      this._description.innerText = options.description;
    }

    this._stopButton = UI.createTextButton(Common.UIString('Stop'), stopCallback, '', true);
    this.contentElement.createChild('div', 'stop-button').appendChild(this._stopButton);
  }

  finish() {
    this._stopTimer();
    this._stopButton.disabled = true;
  }

  hide() {
    this.element.parentNode.classList.remove('tinted');
    this.element.remove();
  }

  /**
   * @param {!Element} parent
   */
  showPane(parent) {
    this.show(parent);
    parent.classList.add('tinted');
    this._stopButton.focus();
  }

  /**
   * @param {string} text
   */
  updateStatus(text) {
    this._status.textContent = text;
  }

  /**
   * @param {string} activity
   * @param {number} percent
   */
  updateProgressBar(activity, percent) {
    this._progressLabel.textContent = activity;
    this._progressBar.style.width = percent.toFixed(1) + '%';
    UI.ARIAUtils.setValueNow(this._progressBar, percent);
    this._updateTimer();
  }

  /**
   * @param {string} caption
   */
  updateButton(caption) {
    this._stopButton.innerText = caption;
  }

  startTimer() {
    this._startTime = Date.now();
    this._timeUpdateTimer = setInterval(this._updateTimer.bind(this, false), 1000);
    this._updateTimer();
  }

  _stopTimer() {
    if (!this._timeUpdateTimer) {
      return;
    }
    clearInterval(this._timeUpdateTimer);
    this._updateTimer(true);
    delete this._timeUpdateTimer;
  }

  /**
   * @param {boolean=} precise
   */
  _updateTimer(precise) {
    if (!this._timeUpdateTimer) {
      return;
    }
    const elapsed = (Date.now() - this._startTime) / 1000;
    this._time.textContent = Common.UIString('%s\xa0sec', elapsed.toFixed(precise ? 1 : 0));
  }
};


/**
 * @implements {Common.QueryParamHandler}
 * @unrestricted
 */
Timeline.LoadTimelineHandler = class {
  /**
   * @override
   * @param {string} value
   */
  handleQueryParam(value) {
    UI.viewManager.showView('timeline').then(() => {
      Timeline.TimelinePanel.instance()._loadFromURL(window.decodeURIComponent(value));
    });
  }
};

/**
 * @implements {UI.ActionDelegate}
 * @unrestricted
 */
Timeline.TimelinePanel.ActionDelegate = class {
  /**
   * @override
   * @param {!UI.Context} context
   * @param {string} actionId
   * @return {boolean}
   */
  handleAction(context, actionId) {
    const panel = UI.context.flavor(Timeline.TimelinePanel);
    console.assert(panel && panel instanceof Timeline.TimelinePanel);
    switch (actionId) {
      case 'timeline.toggle-recording':
        panel._toggleRecording();
        return true;
      case 'timeline.record-reload':
        panel._recordReload();
        return true;
      case 'timeline.save-to-file':
        panel._saveToFile();
        return true;
      case 'timeline.load-from-file':
        panel._selectFileToLoad();
        return true;
      case 'timeline.jump-to-previous-frame':
        panel._jumpToFrame(-1);
        return true;
      case 'timeline.jump-to-next-frame':
        panel._jumpToFrame(1);
        return true;
      case 'timeline.show-history':
        panel._showHistory();
        return true;
      case 'timeline.previous-recording':
        panel._navigateHistory(1);
        return true;
      case 'timeline.next-recording':
        panel._navigateHistory(-1);
        return true;
    }
    return false;
  }
};

Timeline.TimelinePanel._traceProviderSettingSymbol = Symbol('traceProviderSetting');
