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

/**
 * @implements {PerfUI.FlameChartDelegate}
 * @implements {UI.Searchable}
 * @unrestricted
 */
Timeline.TimelineFlameChartView = class extends UI.VBox {
  /**
   * @param {!Timeline.TimelineModeViewDelegate} delegate
   */
  constructor(delegate) {
    super();
    this.element.classList.add('timeline-flamechart');
    this._delegate = delegate;
    /** @type {?Timeline.PerformanceModel} */
    this._model = null;
    /** @type {!Array<number>|undefined} */
    this._searchResults;
    /** @type {!Array<!Common.EventTarget.EventDescriptor>} */
    this._eventListeners = [];

    this._showMemoryGraphSetting = Common.settings.createSetting('timelineShowMemory', false);

    // Create main and network flamecharts.
    this._networkSplitWidget = new UI.SplitWidget(false, false, 'timelineFlamechartMainView', 150);

    const mainViewGroupExpansionSetting = Common.settings.createSetting('timelineFlamechartMainViewGroupExpansion', {});
    this._mainDataProvider = new Timeline.TimelineFlameChartDataProvider();
    this._mainDataProvider.addEventListener(
        Timeline.TimelineFlameChartDataProvider.Events.DataChanged, () => this._mainFlameChart.scheduleUpdate());
    this._mainFlameChart = new PerfUI.FlameChart(this._mainDataProvider, this, mainViewGroupExpansionSetting);
    this._mainFlameChart.alwaysShowVerticalScroll();
    this._mainFlameChart.enableRuler(false);

    this._networkFlameChartGroupExpansionSetting =
        Common.settings.createSetting('timelineFlamechartNetworkViewGroupExpansion', {});
    this._networkDataProvider = new Timeline.TimelineFlameChartNetworkDataProvider();
    this._networkFlameChart = new PerfUI.FlameChart(
        this._networkDataProvider, this, this._networkFlameChartGroupExpansionSetting);
    this._networkFlameChart.alwaysShowVerticalScroll();
    this._networkFlameChart.disableRangeSelection();

    this._networkPane = new UI.VBox();
    this._networkPane.setMinimumSize(23, 23);
    this._networkFlameChart.show(this._networkPane.element);
    this._splitResizer = this._networkPane.element.createChild('div', 'timeline-flamechart-resizer');
    this._networkSplitWidget.hideDefaultResizer(true);
    this._networkSplitWidget.installResizer(this._splitResizer);

    this._networkSplitWidget.setMainWidget(this._mainFlameChart);
    this._networkSplitWidget.setSidebarWidget(this._networkPane);

    // Create counters chart splitter.
    this._chartSplitWidget = new UI.SplitWidget(false, true, 'timelineCountersSplitViewState');
    this._countersView = new Timeline.CountersGraph(this._delegate);
    this._chartSplitWidget.setMainWidget(this._networkSplitWidget);
    this._chartSplitWidget.setSidebarWidget(this._countersView);
    this._chartSplitWidget.hideDefaultResizer();
    this._chartSplitWidget.installResizer(/** @type {!Element} */ (this._countersView.resizerElement()));
    this._updateCountersGraphToggle();

    // Create top level properties splitter.
    this._detailsSplitWidget = new UI.SplitWidget(false, true, 'timelinePanelDetailsSplitViewState');
    this._detailsSplitWidget.element.classList.add('timeline-details-split');
    this._detailsView = new Timeline.TimelineDetailsView(delegate);
    this._detailsSplitWidget.installResizer(this._detailsView.headerElement());
    this._detailsSplitWidget.setMainWidget(this._chartSplitWidget);
    this._detailsSplitWidget.setSidebarWidget(this._detailsView);
    this._detailsSplitWidget.show(this.element);

    this._onMainEntrySelected = this._onEntrySelected.bind(this, this._mainDataProvider);
    this._onNetworkEntrySelected = this._onEntrySelected.bind(this, this._networkDataProvider);
    this._mainFlameChart.addEventListener(PerfUI.FlameChart.Events.EntrySelected, this._onMainEntrySelected, this);
    this._mainFlameChart.addEventListener(PerfUI.FlameChart.Events.EntryInvoked, this._onMainEntrySelected, this);
    this._networkFlameChart.addEventListener(PerfUI.FlameChart.Events.EntrySelected, this._onNetworkEntrySelected, this);
    this._networkFlameChart.addEventListener(PerfUI.FlameChart.Events.EntryInvoked, this._onNetworkEntrySelected, this);
    this._mainFlameChart.addEventListener(PerfUI.FlameChart.Events.EntryHighlighted, this._onEntryHighlighted, this);
    this._nextExtensionIndex = 0;

    this._boundRefresh = this._refresh.bind(this);
    this._selectedTrack = null;

    this._mainDataProvider.setEventColorMapping(Timeline.TimelineUIUtils.eventColor);
    this._groupBySetting =
        Common.settings.createSetting('timelineTreeGroupBy', Timeline.AggregatedTimelineTreeView.GroupBy.None);
    this._groupBySetting.addChangeListener(this._updateColorMapper, this);
    this._updateColorMapper();
  }

  _updateColorMapper() {
    /** @type {!Map<string, string>} */
    this._urlToColorCache = new Map();
    if (!this._model) {
      return;
    }
    this._mainDataProvider.setEventColorMapping(Timeline.TimelineUIUtils.eventColor);
    this._mainFlameChart.update();
  }

  /**
   * @param {!Common.Event} event
   */
  _onWindowChanged(event) {
    const window = /** @type {!Timeline.PerformanceModel.Window} */ (event.data.window);
    const animate = !!event.data.animate;
    this._mainFlameChart.setWindowTimes(window.left, window.right, animate);
    this._networkFlameChart.setWindowTimes(window.left, window.right, animate);
    this._networkDataProvider.setWindowTimes(window.left, window.right);
    this._updateSearchResults(false, false);
  }

  /**
   * @override
   * @param {number} windowStartTime
   * @param {number} windowEndTime
   * @param {boolean} animate
   */
  windowChanged(windowStartTime, windowEndTime, animate) {
    this._model.setWindow({left: windowStartTime, right: windowEndTime}, animate);
  }

  /**
   * @override
   * @param {number} startTime
   * @param {number} endTime
   */
  updateRangeSelection(startTime, endTime) {
    this._delegate.select(Timeline.TimelineSelection.fromRange(startTime, endTime));
  }

  /**
   * @override
   * @param {!PerfUI.FlameChart} flameChart
   * @param {?PerfUI.FlameChart.Group} group
   */
  updateSelectedGroup(flameChart, group) {
    if (flameChart !== this._mainFlameChart) {
      return;
    }
    const track = group ? this._mainDataProvider.groupTrack(group) : null;
    this._selectedTrack = track;
    this._updateTrack();
  }

  /**
   * @param {?Timeline.PerformanceModel} model
   */
  setModel(model) {
    if (model === this._model) {
      return;
    }
    Common.EventTarget.removeEventListeners(this._eventListeners);
    this._model = model;
    this._selectedTrack = null;
    this._mainDataProvider.setModel(this._model);
    this._networkDataProvider.setModel(this._model);
    if (this._model) {
      this._eventListeners = [
        this._model.addEventListener(Timeline.PerformanceModel.Events.WindowChanged, this._onWindowChanged, this),
        this._model.addEventListener(
            Timeline.PerformanceModel.Events.ExtensionDataAdded, this._appendExtensionData, this)
      ];
      const window = model.window();
      this._mainFlameChart.setWindowTimes(window.left, window.right);
      this._networkFlameChart.setWindowTimes(window.left, window.right);
      this._networkDataProvider.setWindowTimes(window.left, window.right);
      this._updateSearchResults(false, false);
    }
    this._updateColorMapper();
    this._updateTrack();
    this._nextExtensionIndex = 0;
    this._appendExtensionData();
    this._refresh();
  }

  _updateTrack() {
    this._countersView.setModel(this._model, this._selectedTrack);
    this._detailsView.setModel(this._model, this._selectedTrack);
  }

  _refresh() {
    if (this._networkDataProvider.isEmpty()) {
      this._mainFlameChart.enableRuler(true);
      this._networkSplitWidget.hideSidebar();
    } else {
      this._mainFlameChart.enableRuler(false);
      this._networkSplitWidget.showBoth();
      this.resizeToPreferredHeights();
    }
    this._mainFlameChart.reset();
    this._networkFlameChart.reset();
    this._updateSearchResults(false, false);
  }

  _appendExtensionData() {
    if (!this._model) {
      return;
    }
    const extensions = this._model.extensionInfo();
    while (this._nextExtensionIndex < extensions.length) {
      this._mainDataProvider.appendExtensionEvents(extensions[this._nextExtensionIndex++]);
    }
    this._mainFlameChart.scheduleUpdate();
  }

  /**
   * @param {!Common.Event} commonEvent
   */
  _onEntryHighlighted(commonEvent) {
    SDK.OverlayModel.hideDOMNodeHighlight();
    const entryIndex = /** @type {number} */ (commonEvent.data);
    const event = this._mainDataProvider.eventByIndex(entryIndex);
    if (!event) {
      return;
    }
    const target = this._model && this._model.timelineModel().targetByEvent(event);
    if (!target) {
      return;
    }
    const timelineData = TimelineModel.TimelineData.forEvent(event);
    const backendNodeId = timelineData.backendNodeId;
    if (!backendNodeId) {
      return;
    }
    new SDK.DeferredDOMNode(target, backendNodeId).highlight();
  }

  /**
   * @param {?SDK.TracingModel.Event} event
   */
  highlightEvent(event) {
    const entryIndex =
        event ? this._mainDataProvider.entryIndexForSelection(Timeline.TimelineSelection.fromTraceEvent(event)) : -1;
    if (entryIndex >= 0) {
      this._mainFlameChart.highlightEntry(entryIndex);
    } else {
      this._mainFlameChart.hideHighlight();
    }
  }

  /**
   * @override
   */
  willHide() {
    this._networkFlameChartGroupExpansionSetting.removeChangeListener(this.resizeToPreferredHeights, this);
    this._showMemoryGraphSetting.removeChangeListener(this._updateCountersGraphToggle, this);
    Bindings.blackboxManager.removeChangeListener(this._boundRefresh);
  }

  /**
   * @override
   */
  wasShown() {
    this._networkFlameChartGroupExpansionSetting.addChangeListener(this.resizeToPreferredHeights, this);
    this._showMemoryGraphSetting.addChangeListener(this._updateCountersGraphToggle, this);
    Bindings.blackboxManager.addChangeListener(this._boundRefresh);
    if (this._needsResizeToPreferredHeights) {
      this.resizeToPreferredHeights();
    }
    this._mainFlameChart.scheduleUpdate();
    this._networkFlameChart.scheduleUpdate();
  }

  _updateCountersGraphToggle() {
    if (this._showMemoryGraphSetting.get()) {
      this._chartSplitWidget.showBoth();
    } else {
      this._chartSplitWidget.hideSidebar();
    }
  }

  /**
   * @param {?Timeline.TimelineSelection} selection
   */
  setSelection(selection) {
    let index = this._mainDataProvider.entryIndexForSelection(selection);
    this._mainFlameChart.setSelectedEntry(index);
    index = this._networkDataProvider.entryIndexForSelection(selection);
    this._networkFlameChart.setSelectedEntry(index);
    if (this._detailsView) {
      this._detailsView.setSelection(selection);
    }
  }

  /**
   * @param {!PerfUI.FlameChartDataProvider} dataProvider
   * @param {!Common.Event} event
   */
  _onEntrySelected(dataProvider, event) {
    const entryIndex = /** @type{number} */ (event.data);
    if (Root.Runtime.experiments.isEnabled('timelineEventInitiators') && dataProvider === this._mainDataProvider) {
      if (this._mainDataProvider.buildFlowForInitiator(entryIndex)) {
        this._mainFlameChart.scheduleUpdate();
      }
    }
    this._delegate.select(dataProvider.createSelection(entryIndex));
  }

  resizeToPreferredHeights() {
    if (!this.isShowing()) {
      this._needsResizeToPreferredHeights = true;
      return;
    }
    this._needsResizeToPreferredHeights = false;
    this._networkPane.element.classList.toggle(
        'timeline-network-resizer-disabled', !this._networkDataProvider.isExpanded());
    this._networkSplitWidget.setSidebarSize(
        this._networkDataProvider.preferredHeight() + this._splitResizer.clientHeight + PerfUI.FlameChart.HeaderHeight +
        2);
  }

  /**
   * @param {!UI.SearchableView} searchableView
   */
  setSearchableView(searchableView) {
    this._searchableView = searchableView;
  }

  // UI.Searchable implementation

  /**
   * @override
   */
  jumpToNextSearchResult() {
    if (!this._searchResults || !this._searchResults.length) {
      return;
    }
    const index = typeof this._selectedSearchResult !== 'undefined' ?
        this._searchResults.indexOf(this._selectedSearchResult) :
        -1;
    this._selectSearchResult(mod(index + 1, this._searchResults.length));
  }

  /**
   * @override
   */
  jumpToPreviousSearchResult() {
    if (!this._searchResults || !this._searchResults.length) {
      return;
    }
    const index =
        typeof this._selectedSearchResult !== 'undefined' ? this._searchResults.indexOf(this._selectedSearchResult) : 0;
    this._selectSearchResult(mod(index - 1, this._searchResults.length));
  }

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

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

  /**
   * @param {number} index
   */
  _selectSearchResult(index) {
    this._searchableView.updateCurrentMatchIndex(index);
    this._selectedSearchResult = this._searchResults[index];
    this._delegate.select(this._mainDataProvider.createSelection(this._selectedSearchResult));
  }

  /**
   * @param {boolean} shouldJump
   * @param {boolean=} jumpBackwards
   */
  _updateSearchResults(shouldJump, jumpBackwards) {
    const oldSelectedSearchResult = this._selectedSearchResult;
    delete this._selectedSearchResult;
    this._searchResults = [];
    if (!this._searchRegex || !this._model) {
      return;
    }
    const regExpFilter = new Timeline.TimelineFilters.RegExp(this._searchRegex);
    const window = this._model.window();
    this._searchResults = this._mainDataProvider.search(window.left, window.right, regExpFilter);
    this._searchableView.updateSearchMatchesCount(this._searchResults.length);
    if (!shouldJump || !this._searchResults.length) {
      return;
    }
    let selectedIndex = this._searchResults.indexOf(oldSelectedSearchResult);
    if (selectedIndex === -1) {
      selectedIndex = jumpBackwards ? this._searchResults.length - 1 : 0;
    }
    this._selectSearchResult(selectedIndex);
  }

  /**
   * @override
   */
  searchCanceled() {
    if (typeof this._selectedSearchResult !== 'undefined') {
      this._delegate.select(null);
    }
    delete this._searchResults;
    delete this._selectedSearchResult;
    delete this._searchRegex;
  }

  /**
   * @override
   * @param {!UI.SearchableView.SearchConfig} searchConfig
   * @param {boolean} shouldJump
   * @param {boolean=} jumpBackwards
   */
  performSearch(searchConfig, shouldJump, jumpBackwards) {
    this._searchRegex = searchConfig.toSearchRegex();
    this._updateSearchResults(shouldJump, jumpBackwards);
  }
};

/**
 * @unrestricted
 */
Timeline.TimelineFlameChartView.Selection = class {
  /**
   * @param {!Timeline.TimelineSelection} selection
   * @param {number} entryIndex
   */
  constructor(selection, entryIndex) {
    this.timelineSelection = selection;
    this.entryIndex = entryIndex;
  }
};

Timeline.FlameChartStyle = {
  textColor: '#333'
};

/**
 * @implements {PerfUI.FlameChartMarker}
 * @unrestricted
 */
Timeline.TimelineFlameChartMarker = class {
  /**
   * @param {number} startTime
   * @param {number} startOffset
   * @param {!Timeline.TimelineMarkerStyle} style
   */
  constructor(startTime, startOffset, style) {
    this._startTime = startTime;
    this._startOffset = startOffset;
    this._style = style;
  }

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

  /**
   * @override
   * @return {string}
   */
  color() {
    return this._style.color;
  }

  /**
   * @override
   * @return {?string}
   */
  title() {
    if (this._style.lowPriority) {
      return null;
    }
    const startTime = Number.millisToString(this._startOffset);
    return ls`${this._style.title} at ${startTime}`;
  }

  /**
   * @override
   * @param {!CanvasRenderingContext2D} context
   * @param {number} x
   * @param {number} height
   * @param {number} pixelsPerMillisecond
   */
  draw(context, x, height, pixelsPerMillisecond) {
    const lowPriorityVisibilityThresholdInPixelsPerMs = 4;

    if (this._style.lowPriority && pixelsPerMillisecond < lowPriorityVisibilityThresholdInPixelsPerMs) {
      return;
    }

    context.save();
    if (this._style.tall) {
      context.strokeStyle = this._style.color;
      context.lineWidth = this._style.lineWidth;
      context.translate(this._style.lineWidth < 1 || (this._style.lineWidth & 1) ? 0.5 : 0, 0.5);
      context.beginPath();
      context.moveTo(x, 0);
      context.setLineDash(this._style.dashStyle);
      context.lineTo(x, context.canvas.height);
      context.stroke();
    }
    context.restore();
  }
};

/** @enum {string} */
Timeline.TimelineFlameChartView._ColorBy = {
  URL: 'URL',
};
