/*
 * Copyright (C) 2019 Apple 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:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
 */

WI.CPUTimelineView = class CPUTimelineView extends WI.TimelineView
{
    constructor(timeline, extraArguments)
    {
        console.assert(timeline.type === WI.TimelineRecord.Type.CPU, timeline);

        super(timeline, extraArguments);

        this._recording = extraArguments.recording;

        this.element.classList.add("cpu");

        this._sectionLimit = CPUTimelineView.defaultSectionLimit;

        this._statisticsData = null;
        this._secondsPerPixelInLayout = undefined;
        this._visibleRecordsInLayout = [];
        this._discontinuitiesInLayout = [];

        this._stickingOverlay = false;
        this._overlayRecord = null;
        this._overlayTime = NaN;

        timeline.addEventListener(WI.Timeline.Event.RecordAdded, this._cpuTimelineRecordAdded, this);
    }

    // Static

    static displayNameForSampleType(type)
    {
        switch (type) {
        case CPUTimelineView.SampleType.JavaScript:
            return WI.UIString("JavaScript");
        case CPUTimelineView.SampleType.Layout:
            return WI.repeatedUIString.timelineRecordLayout();
        case CPUTimelineView.SampleType.Paint:
            return WI.repeatedUIString.timelineRecordPaint();
        case CPUTimelineView.SampleType.Style:
            return WI.UIString("Styles");
        }
        console.error("Unknown sample type", type);
    }

    static get cpuUsageViewHeight() { return 135; }
    static get threadCPUUsageViewHeight() { return 65; }
    static get indicatorViewHeight() { return 15; }

    static get lowEnergyThreshold() { return 3; }
    static get mediumEnergyThreshold() { return 30; }
    static get highEnergyThreshold() { return 100; }

    static get lowEnergyGraphBoundary() { return 10; }
    static get mediumEnergyGraphBoundary() { return 70; }
    static get highEnergyGraphBoundary() { return 100; }

    static get defaultSectionLimit() { return 5; }

    // Public

    shown()
    {
        super.shown();

        if (this._timelineRuler)
            this._timelineRuler.updateLayout(WI.View.LayoutReason.Resize);
    }

    closed()
    {
        console.assert(this.representedObject instanceof WI.Timeline);
        this.representedObject.removeEventListener(null, null, this);
    }

    reset()
    {
        super.reset();

        this._resetSourcesFilters();

        this.clear();
    }

    clear()
    {
        if (!this.didInitialLayout)
            return;

        this._breakdownChart.clear();
        this._breakdownChart.needsLayout();
        this._clearBreakdownLegend();

        this._energyChart.clear();
        this._energyChart.needsLayout();
        this._clearEnergyImpactText();

        this._clearStatistics();
        this._clearSources();

        function clearUsageView(view) {
            view.clear();

            let markersElement = view.chart.element.querySelector(".markers");
            if (markersElement)
                markersElement.remove();
        }

        clearUsageView(this._cpuUsageView);
        clearUsageView(this._mainThreadUsageView);
        clearUsageView(this._webkitThreadUsageView);
        clearUsageView(this._unknownThreadUsageView);

        this._removeWorkerThreadViews();

        this._sectionLimit = CPUTimelineView.defaultSectionLimit;

        this._statisticsData = null;
        this._secondsPerPixelInLayout = undefined;
        this._visibleRecordsInLayout = [];
        this._discontinuitiesInLayout = [];

        this._stickingOverlay = false;
        this._hideGraphOverlay();
    }

    // Protected

    get showsFilterBar() { return false; }

    get scrollableElements()
    {
        return [this.element];
    }

    initialLayout()
    {
        this.element.style.setProperty("--cpu-usage-combined-view-height", CPUTimelineView.cpuUsageViewHeight + "px");
        this.element.style.setProperty("--cpu-usage-view-height", CPUTimelineView.threadCPUUsageViewHeight + "px");
        this.element.style.setProperty("--cpu-usage-indicator-view-height", CPUTimelineView.indicatorViewHeight + "px");

        let contentElement = this.element.appendChild(document.createElement("div"));
        contentElement.classList.add("content");

        let overviewElement = contentElement.appendChild(document.createElement("div"));
        overviewElement.classList.add("overview");

        function createChartContainer(parentElement, subtitle, tooltip) {
            let chartElement = parentElement.appendChild(document.createElement("div"));
            chartElement.classList.add("chart");

            let chartSubtitleElement = chartElement.appendChild(document.createElement("div"));
            chartSubtitleElement.classList.add("subtitle");
            chartSubtitleElement.textContent = subtitle;
            if (tooltip)
                chartSubtitleElement.title = tooltip;

            let chartFlexContainerElement = chartElement.appendChild(document.createElement("div"));
            chartFlexContainerElement.classList.add("container");
            return chartFlexContainerElement;
        }

        function appendLegendRow(legendElement, sampleType) {
            let rowElement = legendElement.appendChild(document.createElement("div"));
            rowElement.classList.add("row");

            let swatchElement = rowElement.appendChild(document.createElement("div"));
            swatchElement.classList.add("swatch", sampleType);

            let valueContainer = rowElement.appendChild(document.createElement("div"));

            let labelElement = valueContainer.appendChild(document.createElement("div"));
            labelElement.classList.add("label");
            labelElement.textContent = WI.CPUTimelineView.displayNameForSampleType(sampleType);

            let sizeElement = valueContainer.appendChild(document.createElement("div"));
            sizeElement.classList.add("size");

            return sizeElement;
        }

        let breakdownChartContainerElement = createChartContainer(overviewElement, WI.UIString("Main Thread"), WI.UIString("Breakdown of time spent on the main thread"));
        this._breakdownChart = new WI.CircleChart({size: 120, innerRadiusRatio: 0.5});
        this._breakdownChart.segments = Object.values(WI.CPUTimelineView.SampleType);
        this.addSubview(this._breakdownChart);
        breakdownChartContainerElement.appendChild(this._breakdownChart.element);

        this._breakdownLegendElement = breakdownChartContainerElement.appendChild(document.createElement("div"));
        this._breakdownLegendElement.classList.add("legend");

        this._breakdownLegendScriptElement = appendLegendRow(this._breakdownLegendElement, CPUTimelineView.SampleType.JavaScript);
        this._breakdownLegendLayoutElement = appendLegendRow(this._breakdownLegendElement, CPUTimelineView.SampleType.Layout);
        this._breakdownLegendPaintElement = appendLegendRow(this._breakdownLegendElement, CPUTimelineView.SampleType.Paint);
        this._breakdownLegendStyleElement = appendLegendRow(this._breakdownLegendElement, CPUTimelineView.SampleType.Style);

        let dividerElement = overviewElement.appendChild(document.createElement("div"));
        dividerElement.classList.add("divider");

        let energyContainerElement = createChartContainer(overviewElement, WI.UIString("Energy Impact"), WI.UIString("Estimated energy impact."));
        energyContainerElement.classList.add("energy");

        let energyChartElement = energyContainerElement.parentElement;
        let energySubtitleElement = energyChartElement.firstChild;
        let energyInfoElement = energySubtitleElement.appendChild(document.createElement("span"));
        energyInfoElement.classList.add("info", WI.Popover.IgnoreAutoDismissClassName);
        energyInfoElement.textContent = "?";

        this._energyInfoPopover = null;
        this._energyInfoPopoverContentElement = null;
        energyInfoElement.addEventListener("click", (event) => {
            if (!this._energyInfoPopover)
                this._energyInfoPopover = new WI.Popover;

            if (!this._energyInfoPopoverContentElement) {
                this._energyInfoPopoverContentElement = document.createElement("div");
                this._energyInfoPopoverContentElement.className = "energy-info-popover-content";

                const precision = 0;
                let lowPercent = Number.percentageString(CPUTimelineView.lowEnergyThreshold / 100, precision);

                let p1 = this._energyInfoPopoverContentElement.appendChild(document.createElement("p"));
                p1.textContent = WI.UIString("Periods of high CPU utilization will rapidly drain battery. Strive to keep idle pages under %s average CPU utilization.").format(lowPercent);

                let p2 = this._energyInfoPopoverContentElement.appendChild(document.createElement("p"));
                p2.textContent = WI.UIString("There is an incurred energy penalty each time the page enters script. This commonly happens with timers, event handlers, and observers.");

                let p3 = this._energyInfoPopoverContentElement.appendChild(document.createElement("p"));
                p3.textContent = WI.UIString("To improve CPU utilization reduce or batch workloads when the page is not visible or during times when the page is not being interacted with.");
            }

            let isRTL = WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL;
            let preferredEdges = isRTL ? [WI.RectEdge.MAX_Y, WI.RectEdge.MIN_X] : [WI.RectEdge.MAX_Y, WI.RectEdge.MAX_X];
            let calculateTargetFrame = () => WI.Rect.rectFromClientRect(energyInfoElement.getBoundingClientRect()).pad(3);

            this._energyInfoPopover.presentNewContentWithFrame(this._energyInfoPopoverContentElement, calculateTargetFrame(), preferredEdges);
            this._energyInfoPopover.windowResizeHandler = () => {
                this._energyInfoPopover.present(calculateTargetFrame(), preferredEdges);
            };
        });

        this._energyChart = new WI.GaugeChart({
            height: 110,
            strokeWidth: 20,
            segments: [
                {className: "low", limit: CPUTimelineView.lowEnergyGraphBoundary},
                {className: "medium", limit: CPUTimelineView.mediumEnergyGraphBoundary},
                {className: "high", limit: CPUTimelineView.highEnergyGraphBoundary},
            ]
        });
        this.addSubview(this._energyChart);
        energyContainerElement.appendChild(this._energyChart.element);

        let energyTextContainerElement = energyContainerElement.appendChild(document.createElement("div"));

        this._energyImpactLabelElement = energyTextContainerElement.appendChild(document.createElement("div"));
        this._energyImpactLabelElement.className = "energy-impact";

        this._energyImpactNumberElement = energyTextContainerElement.appendChild(document.createElement("div"));
        this._energyImpactNumberElement.className = "energy-impact-number";

        this._energyImpactDurationElement = energyTextContainerElement.appendChild(document.createElement("div"));
        this._energyImpactDurationElement.className = "energy-impact-number";

        let detailsContainerElement = contentElement.appendChild(document.createElement("div"));
        detailsContainerElement.classList.add("details");

        this._timelineRuler = new WI.TimelineRuler;
        this._timelineRuler.zeroTime = this.zeroTime;
        this._timelineRuler.startTime = this.startTime;
        this._timelineRuler.endTime = this.endTime;

        this.addSubview(this._timelineRuler);
        detailsContainerElement.appendChild(this._timelineRuler.element);

        // Cause the TimelineRuler to layout now so we will have some of its
        // important properties initialized for our layout.
        this._timelineRuler.updateLayout(WI.View.LayoutReason.Resize);

        let detailsSubtitleElement = detailsContainerElement.appendChild(document.createElement("div"));
        detailsSubtitleElement.classList.add("subtitle");
        detailsSubtitleElement.textContent = WI.UIString("CPU Usage");

        this._cpuUsageView = new WI.CPUUsageCombinedView(WI.UIString("Total"));
        this.addSubview(this._cpuUsageView);
        detailsContainerElement.appendChild(this._cpuUsageView.element);

        this._cpuUsageView.rangeChart.element.addEventListener("click", this._handleIndicatorClick.bind(this));

        this._threadsDetailsElement = detailsContainerElement.appendChild(document.createElement("details"));
        this._threadsDetailsElement.open = WI.settings.cpuTimelineThreadDetailsExpanded.value;
        this._threadsDetailsElement.addEventListener("toggle", (event) => {
            WI.settings.cpuTimelineThreadDetailsExpanded.value = this._threadsDetailsElement.open;
            if (this._threadsDetailsElement.open)
                this.updateLayout(WI.CPUTimelineView.LayoutReason.Internal);
        });

        let threadsSubtitleElement = this._threadsDetailsElement.appendChild(document.createElement("summary"));
        threadsSubtitleElement.classList.add("subtitle", "threads", "expandable");
        threadsSubtitleElement.textContent = WI.UIString("Threads");

        this._mainThreadUsageView = new WI.CPUUsageView(WI.UIString("Main Thread"));
        this._mainThreadUsageView.element.classList.add("main-thread");
        this.addSubview(this._mainThreadUsageView);
        this._threadsDetailsElement.appendChild(this._mainThreadUsageView.element);

        this._webkitThreadUsageView = new WI.CPUUsageView(WI.UIString("WebKit Threads"));
        this.addSubview(this._webkitThreadUsageView);
        this._threadsDetailsElement.appendChild(this._webkitThreadUsageView.element);

        this._unknownThreadUsageView = new WI.CPUUsageView(WI.UIString("Other Threads"));
        this.addSubview(this._unknownThreadUsageView);
        this._threadsDetailsElement.appendChild(this._unknownThreadUsageView.element);

        this._workerViews = [];

        this._sourcesFilter = {
            timer: new Set,
            event: new Set,
            observer: new Set,
        };

        let bottomOverviewElement = contentElement.appendChild(document.createElement("div"));
        bottomOverviewElement.classList.add("overview");

        let statisticsContainerElement = createChartContainer(bottomOverviewElement, WI.UIString("Statistics"));
        statisticsContainerElement.classList.add("stats");

        this._statisticsTable = statisticsContainerElement.appendChild(document.createElement("table"));
        this._statisticsRows = [];

        {
            let {headerCell, numberCell} = this._createTableRow(this._statisticsTable);
            headerCell.textContent = WI.UIString("Network Requests:");
            this._networkRequestsNumberElement = numberCell;
        }
        {
            let {headerCell, numberCell} = this._createTableRow(this._statisticsTable);
            headerCell.textContent = WI.UIString("Script Entries:");
            this._scriptEntriesNumberElement = numberCell;
        }

        this._clearStatistics();

        let bottomDividerElement = bottomOverviewElement.appendChild(document.createElement("div"));
        bottomDividerElement.classList.add("divider");

        let sourcesContainerElement = createChartContainer(bottomOverviewElement, WI.UIString("Sources"));
        sourcesContainerElement.classList.add("stats");

        this._sourcesTable = sourcesContainerElement.appendChild(document.createElement("table"));
        this._sourcesRows = [];

        {
            let {row, headerCell, numberCell, labelCell} = this._createTableRow(this._sourcesTable);
            headerCell.textContent = WI.UIString("Filter:");
            this._sourcesFilterRow = row;
            this._sourcesFilterRow.hidden = true;
            this._sourcesFilterNumberElement = numberCell;
            this._sourcesFilterLabelElement = labelCell;

            let filterClearElement = numberCell.appendChild(document.createElement("span"));
            filterClearElement.className = "filter-clear";
            filterClearElement.textContent = multiplicationSign;
            filterClearElement.addEventListener("click", (event) => {
                this._resetSourcesFilters();
                this._layoutStatisticsAndSources();
            });
        }
        {
            let {row, headerCell, numberCell, labelCell} = this._createTableRow(this._sourcesTable);
            headerCell.textContent = WI.UIString("Timers:");
            this._timerInstallationsRow = row;
            this._timerInstallationsNumberElement = numberCell;
            this._timerInstallationsLabelElement = labelCell;
        }
        {
            let {row, headerCell, numberCell, labelCell} = this._createTableRow(this._sourcesTable);
            headerCell.textContent = WI.UIString("Event Handlers:");
            this._eventHandlersRow = row;
            this._eventHandlersNumberElement = numberCell;
            this._eventHandlersLabelElement = labelCell;
        }
        {
            let {row, headerCell, numberCell, labelCell} = this._createTableRow(this._sourcesTable);
            headerCell.textContent = WI.UIString("Observer Handlers:");
            this._observerHandlersRow = row;
            this._observerHandlersNumberElement = numberCell;
            this._observerHandlersLabelElement = labelCell;
        }

        this._clearSources();

        this.element.addEventListener("click", this._handleGraphClick.bind(this));
        this.element.addEventListener("mousemove", this._handleGraphMouseMove.bind(this));

        this._overlayMarker = new WI.TimelineMarker(-1, WI.TimelineMarker.Type.TimeStamp);
        this._timelineRuler.addMarker(this._overlayMarker);
    }

    layout()
    {
        if (this.layoutReason === WI.View.LayoutReason.Resize)
            return;

        if (this.layoutReason !== WI.CPUTimelineView.LayoutReason.Internal)
            this._sectionLimit = CPUTimelineView.defaultSectionLimit;

        // Always update timeline ruler.
        this._timelineRuler.zeroTime = this.zeroTime;
        this._timelineRuler.startTime = this.startTime;
        this._timelineRuler.endTime = this.endTime;

        let secondsPerPixel = this._timelineRuler.secondsPerPixel;
        if (!secondsPerPixel)
            return;

        let graphStartTime = this.startTime;
        let graphEndTime = this.endTime;
        let visibleEndTime = Math.min(this.endTime, this.currentTime);
        let visibleDuration = visibleEndTime - graphStartTime;

        let discontinuities = this._recording.discontinuitiesInTimeRange(graphStartTime, visibleEndTime);
        let originalDiscontinuities = discontinuities.slice();

        let visibleRecords = this.representedObject.recordsInTimeRange(graphStartTime, visibleEndTime, {
            includeRecordBeforeStart: !discontinuities.length || discontinuities[0].startTime > graphStartTime,
            includeRecordAfterEnd: true,
        });
        if (!visibleRecords.length || (visibleRecords.length === 1 && visibleRecords[0].endTime < graphStartTime)) {
            this.clear();
            return;
        }

        this._secondsPerPixelInLayout = secondsPerPixel;
        this._visibleRecordsInLayout = visibleRecords;
        this._discontinuitiesInLayout = discontinuities.slice();

        this._statisticsData = this._computeStatisticsData(graphStartTime, visibleEndTime);
        this._layoutBreakdownChart();
        this._layoutStatisticsAndSources();

        let dataPoints = [];
        let workersDataMap = new Map;
        let workersSeenInCurrentRecord = new Set;

        let max = -Infinity;
        let mainThreadMax = -Infinity;
        let webkitThreadMax = -Infinity;
        let unknownThreadMax = -Infinity;
        let workerMax = -Infinity;

        let min = Infinity;
        let mainThreadMin = Infinity;
        let webkitThreadMin = Infinity;
        let unknownThreadMin = Infinity;

        let average = 0;
        let mainThreadAverage = 0;
        let webkitThreadAverage = 0;
        let unknownThreadAverage = 0;

        for (let record of visibleRecords) {
            let time = record.timestamp;
            let {usage, mainThreadUsage, workerThreadUsage, webkitThreadUsage, unknownThreadUsage} = record;

            if (discontinuities.length && discontinuities[0].endTime <= time) {
                let startDiscontinuity = discontinuities.shift();
                let endDiscontinuity = startDiscontinuity;
                while (discontinuities.length && discontinuities[0].endTime <= time)
                    endDiscontinuity = discontinuities.shift();

                if (dataPoints.length) {
                    let previousDataPoint = dataPoints.lastValue;
                    dataPoints.push({
                        time: startDiscontinuity.startTime,
                        mainThreadUsage: previousDataPoint.mainThreadUsage,
                        workerThreadUsage: previousDataPoint.workerThreadUsage,
                        webkitThreadUsage: previousDataPoint.webkitThreadUsage,
                        unknownThreadUsage: previousDataPoint.unknownThreadUsage,
                        usage: previousDataPoint.usage,
                    });
                }

                dataPoints.push({time: startDiscontinuity.startTime, mainThreadUsage: 0, workerThreadUsage: 0, webkitThreadUsage: 0, unknownThreadUsage: 0, usage: 0});
                dataPoints.push({time: endDiscontinuity.endTime, mainThreadUsage: 0, workerThreadUsage: 0, webkitThreadUsage: 0, unknownThreadUsage: 0, usage: 0});
                dataPoints.push({time: endDiscontinuity.endTime, mainThreadUsage, workerThreadUsage, webkitThreadUsage, unknownThreadUsage, usage});
            }

            dataPoints.push({time, mainThreadUsage, workerThreadUsage, webkitThreadUsage, unknownThreadUsage, usage});

            max = Math.max(max, usage);
            mainThreadMax = Math.max(mainThreadMax, mainThreadUsage);
            webkitThreadMax = Math.max(webkitThreadMax, webkitThreadUsage);
            unknownThreadMax = Math.max(unknownThreadMax, unknownThreadUsage);

            min = Math.min(min, usage);
            mainThreadMin = Math.min(mainThreadMin, mainThreadUsage);
            webkitThreadMin = Math.min(webkitThreadMin, webkitThreadUsage);
            unknownThreadMin = Math.min(unknownThreadMin, unknownThreadUsage);

            average += usage;
            mainThreadAverage += mainThreadUsage;
            webkitThreadAverage += webkitThreadUsage;
            unknownThreadAverage += unknownThreadUsage;

            let workersSeenInLastRecord = workersSeenInCurrentRecord;
            workersSeenInCurrentRecord = new Set;

            if (record.workersData && record.workersData.length) {
                for (let {targetId, usage} of record.workersData) {
                    workersSeenInCurrentRecord.add(targetId);
                    let workerData = workersDataMap.get(targetId);
                    if (!workerData) {
                        workerData = {
                            discontinuities: originalDiscontinuities.slice(),
                            recordsCount: 0,
                            dataPoints: [],
                            min: Infinity,
                            max: -Infinity,
                            average: 0
                        };

                        while (workerData.discontinuities.length && workerData.discontinuities[0].endTime <= graphStartTime)
                            workerData.discontinuities.shift();
                        workerData.dataPoints.push({time: graphStartTime, usage: 0});
                        workerData.dataPoints.push({time, usage: 0});
                        workersDataMap.set(targetId, workerData);
                    }

                    if (workerData.discontinuities.length && workerData.discontinuities[0].endTime < time) {
                        let startDiscontinuity = workerData.discontinuities.shift();
                        let endDiscontinuity = startDiscontinuity;
                        while (workerData.discontinuities.length && workerData.discontinuities[0].endTime < time)
                            endDiscontinuity = workerData.discontinuities.shift();
                        if (workerData.dataPoints.length) {
                            let previousDataPoint = workerData.dataPoints.lastValue;
                            workerData.dataPoints.push({time: startDiscontinuity.startTime, usage: previousDataPoint.usage});
                        }
                        workerData.dataPoints.push({time: startDiscontinuity.startTime, usage: 0});
                        workerData.dataPoints.push({time: endDiscontinuity.endTime, usage: 0});
                        workerData.dataPoints.push({time: endDiscontinuity.endTime, usage});
                    }

                    workerData.dataPoints.push({time, usage});
                    workerData.recordsCount += 1;
                    workerData.max = Math.max(workerData.max, usage);
                    workerData.min = Math.min(workerData.min, usage);
                    workerData.average += usage;
                }
            }

            // Close any worker that died by dropping to zero.
            if (workersSeenInLastRecord.size) {
                let deadWorkers = workersSeenInLastRecord.difference(workersSeenInCurrentRecord);
                for (let workerId of deadWorkers) {
                    let workerData = workersDataMap.get(workerId);
                    if (workerData.dataPoints.lastValue.usage !== 0)
                        workerData.dataPoints.push({time, usage: 0});
                }
            }
        }

        average /= visibleRecords.length;
        mainThreadAverage /= visibleRecords.length;
        webkitThreadAverage /= visibleRecords.length;
        unknownThreadAverage /= visibleRecords.length;

        for (let [workerId, workerData] of workersDataMap) {
            workerData.average = workerData.average / workerData.recordsCount;
            if (workerData.max > workerMax)
                workerMax = workerData.max;
        }

        // If the graph end time is inside a gap, the last data point should
        // only be extended to the start of the discontinuity.
        if (discontinuities.length)
            visibleEndTime = discontinuities[0].startTime;

        function bestThreadLayoutMax(value) {
            if (value > 100)
                return Math.ceil(value);
            return (Math.floor(value / 25) + 1) * 25;
        }

        function removeGreaterThan(arr, max) {
            return arr.filter((x) => x <= max);
        }

        function markerValuesForMaxValue(max) {
            if (max < 1)
                return [0.5];
            if (max < 7)
                return removeGreaterThan([1, 3, 5], max);
            if (max < 12.5)
                return removeGreaterThan([5, 10], max);
            if (max < 20)
                return removeGreaterThan([5, 10, 15], max);
            if (max < 30)
                return removeGreaterThan([10, 20, 30], max);
            if (max < 50)
                return removeGreaterThan([15, 30, 45], max);
            if (max < 100)
                return removeGreaterThan([25, 50, 75], max);
            if (max < 200)
                return removeGreaterThan([50, 100, 150], max);
            if (max >= 200) {
                let hundreds = Math.floor(max / 100);
                let even = (hundreds % 2) === 0;
                if (even) {
                    let top = hundreds * 100;
                    let bottom = top / 2;
                    return [bottom, top];
                }
                let top = hundreds * 100;
                let bottom = 100;
                let mid = (top + bottom) / 2;
                return [bottom, mid, top];
            }
        }

        function layoutView(view, property, graphHeight, layoutMax, {dataPoints, min, max, average}) {
            if (min === Infinity)
                min = 0;
            if (max === -Infinity)
                max = 0;
            if (layoutMax === -Infinity)
                layoutMax = 0;

            let isAllThreadsGraph = property === null;

            let graphMax = layoutMax * 1.05;

            function xScale(time) {
                return (time - graphStartTime) / secondsPerPixel;
            }

            let size = new WI.Size(xScale(graphEndTime), graphHeight);

            function yScale(value) {
                return size.height - ((value / graphMax) * size.height);
            }

            view.updateChart(dataPoints, size, visibleEndTime, min, max, average, xScale, yScale, property);

            let markersElement = view.chart.element.querySelector(".markers");
            if (!markersElement) {
                markersElement = view.chart.element.appendChild(document.createElement("div"));
                markersElement.className = "markers";
            }
            markersElement.removeChildren();

            let markerValues;
            if (isAllThreadsGraph)
                markerValues = markerValuesForMaxValue(max);
            else {
                const minimumMarkerTextHeight = 17;
                let percentPerPixel = 1 / (graphHeight / layoutMax);
                if (layoutMax < 5) {
                    let minimumDisplayablePercentByTwo = Math.ceil((minimumMarkerTextHeight * percentPerPixel) / 2) * 2;
                    markerValues = [Math.max(minimumDisplayablePercentByTwo, Math.floor(max))];
                } else {
                    let minimumDisplayablePercentByFive = Math.ceil((minimumMarkerTextHeight * percentPerPixel) / 5) * 5;
                    markerValues = [Math.max(minimumDisplayablePercentByFive, Math.floor(max))];
                }
            }

            for (let value of markerValues) {
                let marginTop = yScale(value);

                let markerElement = markersElement.appendChild(document.createElement("div"));
                markerElement.style.marginTop = marginTop.toFixed(2) + "px";

                let labelElement = markerElement.appendChild(document.createElement("span"));
                labelElement.classList.add("label");
                const precision = 0;
                labelElement.innerText = Number.percentageString(value / 100, precision);
            }
        }

        // Layout the combined graph to the maximum total CPU usage.
        // Layout all the thread graphs to the same time scale, the maximum across threads / thread groups.
        this._layoutMax = max;
        this._threadLayoutMax = bestThreadLayoutMax(Math.max(mainThreadMax, webkitThreadMax, unknownThreadMax, workerMax));

        layoutView(this._cpuUsageView, null, CPUTimelineView.cpuUsageViewHeight, this._layoutMax, {dataPoints, min, max, average});

        if (this._threadsDetailsElement.open) {
            layoutView(this._mainThreadUsageView, "mainThreadUsage", CPUTimelineView.threadCPUUsageViewHeight, this._threadLayoutMax, {dataPoints, min: mainThreadMin, max: mainThreadMax, average: mainThreadAverage});
            layoutView(this._webkitThreadUsageView, "webkitThreadUsage", CPUTimelineView.threadCPUUsageViewHeight, this._threadLayoutMax, {dataPoints, min: webkitThreadMin, max: webkitThreadMax, average: webkitThreadAverage});
            layoutView(this._unknownThreadUsageView, "unknownThreadUsage", CPUTimelineView.threadCPUUsageViewHeight, this._threadLayoutMax, {dataPoints, min: unknownThreadMin, max: unknownThreadMax, average: unknownThreadAverage});

            this._removeWorkerThreadViews();

            for (let [workerId, workerData] of workersDataMap) {
                let worker = WI.targetManager.targetForIdentifier(workerId);
                let displayName = worker ? worker.displayName : WI.UIString("Worker Thread");
                let workerView = new WI.CPUUsageView(displayName);
                workerView.element.classList.add("worker-thread");
                workerView.__workerId = workerId;
                this.addSubview(workerView);
                this._threadsDetailsElement.insertBefore(workerView.element, this._webkitThreadUsageView.element);
                this._workerViews.push(workerView);

                layoutView(workerView, "usage", CPUTimelineView.threadCPUUsageViewHeight, this._threadLayoutMax, {dataPoints: workerData.dataPoints, min: workerData.min, max: workerData.max, average: workerData.average});
            }
        }

        function xScaleIndicatorRange(sampleIndex) {
            return (sampleIndex / 1000) / secondsPerPixel;
        }

        let graphWidth = (graphEndTime - graphStartTime) / secondsPerPixel;
        let size = new WI.Size(graphWidth, CPUTimelineView.indicatorViewHeight);
        this._cpuUsageView.updateMainThreadIndicator(this._statisticsData.samples, size, visibleEndTime, xScaleIndicatorRange);

        this._layoutEnergyChart(average, visibleDuration);

        this._updateGraphOverlay();
    }

    // Private

    _layoutBreakdownChart()
    {
        let {samples, samplesScript, samplesLayout, samplesPaint, samplesStyle, samplesIdle} = this._statisticsData;

        let nonIdleSamplesCount = samples.length - samplesIdle;
        if (!nonIdleSamplesCount) {
            this._breakdownChart.clear();
            this._breakdownChart.needsLayout();
            this._clearBreakdownLegend();
            return;
        }

        let percentScript = samplesScript / nonIdleSamplesCount;
        let percentLayout = samplesLayout / nonIdleSamplesCount;
        let percentPaint = samplesPaint / nonIdleSamplesCount;
        let percentStyle = samplesStyle / nonIdleSamplesCount;

        this._breakdownLegendScriptElement.textContent = `${Number.percentageString(percentScript)} (${samplesScript})`;
        this._breakdownLegendLayoutElement.textContent = `${Number.percentageString(percentLayout)} (${samplesLayout})`;
        this._breakdownLegendPaintElement.textContent = `${Number.percentageString(percentPaint)} (${samplesPaint})`;
        this._breakdownLegendStyleElement.textContent = `${Number.percentageString(percentStyle)} (${samplesStyle})`;

        this._breakdownChart.values = [percentScript * 100, percentLayout * 100, percentPaint * 100, percentStyle * 100];
        this._breakdownChart.needsLayout();

        let centerElement = this._breakdownChart.centerElement;
        let samplesElement = centerElement.firstChild;
        if (!samplesElement) {
            samplesElement = centerElement.appendChild(document.createElement("div"));
            samplesElement.classList.add("samples");
            samplesElement.title = WI.UIString("Time spent on the main thread");
        }

        let millisecondsStringNoDecimal = WI.UIString("%.0fms").format(nonIdleSamplesCount);
        samplesElement.textContent = millisecondsStringNoDecimal;
    }

    _layoutStatisticsAndSources()
    {
        this._layoutStatisticsSection();
        this._layoutSourcesSection();
    }

    _layoutStatisticsSection()
    {
        let statistics = this._statisticsData;

        this._clearStatistics();

        this._networkRequestsNumberElement.textContent = statistics.networkRequests;
        this._scriptEntriesNumberElement.textContent = statistics.scriptEntries;

        let createFilterElement = (type, name) => {
            let span = document.createElement("span");
            span.className = "filter";
            span.textContent = name;
            span.addEventListener("mouseup", (event) => {
                if (span.classList.contains("active"))
                    this._removeSourcesFilter(type, name);
                else
                    this._addSourcesFilter(type, name);

                this._layoutStatisticsAndSources();
            });

            span.classList.toggle("active", this._sourcesFilter[type].has(name));

            return span;
        };

        let expandAllSections = () => {
            this._sectionLimit = Infinity;
            this._layoutStatisticsAndSources();
        };

        function createEllipsisElement() {
            let span = document.createElement("span");
            span.className = "show-more";
            span.role = "button";
            span.textContent = ellipsis;
            span.addEventListener("click", (event) => {
                expandAllSections();
            });
            return span;
        }

        // Sort a Map of key => count values in descending order.
        function sortMapByEntryCount(map) {
            let entries = Array.from(map);
            entries.sort((entryA, entryB) => entryB[1] - entryA[1]);
            return new Map(entries);
        }

        if (statistics.timerTypes.size) {
            let i = 0;
            let sorted = sortMapByEntryCount(statistics.timerTypes);
            for (let [timerType, count] of sorted) {
                let headerValue = i === 0 ? WI.UIString("Timers:") : "";
                let timerTypeElement = createFilterElement("timer", timerType);
                this._insertTableRow(this._statisticsTable, this._statisticsRows, {headerValue, numberValue: count, labelValue: timerTypeElement});

                if (++i === this._sectionLimit && sorted.size > this._sectionLimit) {
                    this._insertTableRow(this._statisticsTable, this._statisticsRows, {labelValue: createEllipsisElement()});
                    break;
                }
            }
        }

        if (statistics.eventTypes.size) {
            let i = 0;
            let sorted = sortMapByEntryCount(statistics.eventTypes);
            for (let [eventType, count] of sorted) {
                let headerValue = i === 0 ? WI.UIString("Events:") : "";
                let eventTypeElement = createFilterElement("event", eventType);
                this._insertTableRow(this._statisticsTable, this._statisticsRows, {headerValue, numberValue: count, labelValue: eventTypeElement});

                if (++i === this._sectionLimit && sorted.size > this._sectionLimit) {
                    this._insertTableRow(this._statisticsTable, this._statisticsRows, {labelValue: createEllipsisElement()});
                    break;
                }
            }
        }

        if (statistics.observerTypes.size) {
            let i = 0;
            let sorted = sortMapByEntryCount(statistics.observerTypes);
            for (let [observerType, count] of sorted) {
                let headerValue = i === 0 ? WI.UIString("Observers:") : "";
                let observerTypeElement = createFilterElement("observer", observerType);
                this._insertTableRow(this._statisticsTable, this._statisticsRows, {headerValue, numberValue: count, labelValue: observerTypeElement});

                if (++i === this._sectionLimit && sorted.size > this._sectionLimit) {
                    this._insertTableRow(this._statisticsTable, this._statisticsRows, {labelValue: createEllipsisElement()});
                    break;
                }
            }
        }
    }

    _layoutSourcesSection()
    {
        let statistics = this._statisticsData;

        this._clearSources();

        const unknownLocationKey = "unknown";

        function keyForSourceCodeLocation(sourceCodeLocation) {
            if (!sourceCodeLocation)
                return unknownLocationKey;

            return sourceCodeLocation.sourceCode.url + ":" + sourceCodeLocation.lineNumber + ":" + sourceCodeLocation.columnNumber;
        }

        function labelForLocation(key, sourceCodeLocation, functionName) {
            if (key === unknownLocationKey) {
                let span = document.createElement("span");
                span.className = "unknown";
                span.textContent = WI.UIString("Unknown Location");
                return span;
            }

            const options = {
                nameStyle: WI.SourceCodeLocation.NameStyle.Short,
                columnStyle: WI.SourceCodeLocation.ColumnStyle.Shown,
                dontFloat: true,
                ignoreNetworkTab: true,
                ignoreSearchTab: true,
            };
            return WI.createSourceCodeLocationLink(sourceCodeLocation, options);
        }

        let timerFilters = this._sourcesFilter.timer;
        let eventFilters = this._sourcesFilter.event;
        let observerFilters = this._sourcesFilter.observer;
        let hasFilters = (timerFilters.size || eventFilters.size || observerFilters.size);

        let sectionLimit = this._sectionLimit;
        if (isFinite(sectionLimit) && hasFilters)
            sectionLimit = CPUTimelineView.defaultSectionLimit * 2;

        let expandAllSections = () => {
            this._sectionLimit = Infinity;
            this._layoutStatisticsAndSources();
        };

        function createEllipsisElement() {
            let span = document.createElement("span");
            span.className = "show-more";
            span.role = "button";
            span.textContent = ellipsis;
            span.addEventListener("click", (event) => {
                expandAllSections();
            });
            return span;
        }

        let timerMap = new Map;
        let eventHandlerMap = new Map;
        let observerCallbackMap = new Map;
        let seenTimers = new Set;

        if (!hasFilters || timerFilters.size) {
            // Aggregate timers on the location where the timers were installed.
            // For repeating timers, this includes the total counts the interval fired in the selected time range.
            for (let record of statistics.timerInstallationRecords) {
                if (timerFilters.size) {
                    if (record.eventType === WI.ScriptTimelineRecord.EventType.AnimationFrameRequested && !timerFilters.has("requestAnimationFrame"))
                        continue;
                    if (record.eventType === WI.ScriptTimelineRecord.EventType.TimerInstalled && !timerFilters.has("setTimeout"))
                        continue;
                }

                let callFrame = record.initiatorCallFrame;
                let sourceCodeLocation = callFrame ? callFrame.sourceCodeLocation : record.sourceCodeLocation;
                let functionName = callFrame ? callFrame.functionName : "";
                let key = keyForSourceCodeLocation(sourceCodeLocation);
                let entry = timerMap.getOrInitialize(key, {sourceCodeLocation, functionName, count: 0, repeating: false});
                if (record.details) {
                    let timerIdentifier = record.details.timerId;
                    let repeatingEntry = statistics.repeatingTimers.get(timerIdentifier);
                    let count = repeatingEntry ? repeatingEntry.count : 1;
                    entry.count += count;
                    if (record.details.repeating)
                        entry.repeating = true;
                    seenTimers.add(timerIdentifier);
                } else
                    entry.count += 1;
            }

            // Aggregate repeating timers where we did not see the installation in the selected time range.
            // This will use the source code location of where the timer fired, which is better than nothing.
            if (!hasFilters || timerFilters.has("setTimeout")) {
                for (let [timerId, repeatingEntry] of statistics.repeatingTimers) {
                    if (seenTimers.has(timerId))
                        continue;
                    // FIXME: <https://webkit.org/b/195351> Web Inspector: CPU Usage Timeline - better resolution of installation source for repeated timers
                    // We could have a map of all repeating timer installations in the whole recording
                    // so that we can provide a function name for these repeating timers lacking an installation point.
                    let sourceCodeLocation = repeatingEntry.record.sourceCodeLocation;
                    let key = keyForSourceCodeLocation(sourceCodeLocation);
                    let entry = timerMap.getOrInitialize(key, {sourceCodeLocation, count: 0, repeating: false});
                    entry.count += repeatingEntry.count;
                    entry.repeating = true;
                }
            }
        }

        if (!hasFilters || eventFilters.size) {
            for (let record of statistics.eventHandlerRecords) {
                if (eventFilters.size && !eventFilters.has(record.details))
                    continue;
                let sourceCodeLocation = record.sourceCodeLocation;
                let key = keyForSourceCodeLocation(sourceCodeLocation);
                let entry = eventHandlerMap.getOrInitialize(key, {sourceCodeLocation, count: 0});
                entry.count += 1;
            }
        }

        if (!hasFilters || observerFilters.size) {
            for (let record of statistics.observerCallbackRecords) {
                if (observerFilters.size && !observerFilters.has(record.details))
                    continue;
                let sourceCodeLocation = record.sourceCodeLocation;
                let key = keyForSourceCodeLocation(record.sourceCodeLocation);
                let entry = observerCallbackMap.getOrInitialize(key, {sourceCodeLocation, count: 0});
                entry.count += 1;
            }
        }

        const headerValue = "";

        // Sort a Map of key => {count} objects in descending order.
        function sortMapByEntryCountProperty(map) {
            let entries = Array.from(map);
            entries.sort((entryA, entryB) => entryB[1].count - entryA[1].count);
            return new Map(entries);
        }

        if (timerMap.size) {
            let i = 0;
            let sorted = sortMapByEntryCountProperty(timerMap);
            for (let [key, entry] of sorted) {
                let numberValue = entry.repeating ? WI.UIString("~%s", "Approximate Number", "Approximate count of events").format(entry.count) : entry.count;
                let sourceCodeLocation = entry.callFrame ? entry.callFrame.sourceCodeLocation : entry.sourceCodeLocation;
                let labelValue = labelForLocation(key, sourceCodeLocation);
                let followingRow = this._eventHandlersRow;

                let row;
                if (i === 0) {
                    row = this._timerInstallationsRow;
                    this._timerInstallationsNumberElement.textContent = numberValue;
                    this._timerInstallationsLabelElement.append(labelValue);
                } else
                    row = this._insertTableRow(this._sourcesTable, this._sourcesRows, {headerValue, numberValue, labelValue, followingRow});

                if (entry.functionName)
                    row.querySelector(".label").append(` ${enDash} ${entry.functionName}`);

                if (++i === sectionLimit && sorted.size > sectionLimit) {
                    this._insertTableRow(this._sourcesTable, this._sourcesRows, {labelValue: createEllipsisElement(), followingRow});
                    break;
                }
            }
        }

        if (eventHandlerMap.size) {
            let i = 0;
            let sorted = sortMapByEntryCountProperty(eventHandlerMap);
            for (let [key, entry] of sorted) {
                let numberValue = entry.count;
                let labelValue = labelForLocation(key, entry.sourceCodeLocation);
                let followingRow = this._observerHandlersRow;

                if (i === 0) {
                    this._eventHandlersNumberElement.textContent = numberValue;
                    this._eventHandlersLabelElement.append(labelValue);
                } else
                    this._insertTableRow(this._sourcesTable, this._sourcesRows, {headerValue, numberValue, labelValue, followingRow});

                if (++i === sectionLimit && sorted.size > sectionLimit) {
                    this._insertTableRow(this._sourcesTable, this._sourcesRows, {labelValue: createEllipsisElement(), followingRow});
                    break;
                }
            }
        }

        if (observerCallbackMap.size) {
            let i = 0;
            let sorted = sortMapByEntryCountProperty(observerCallbackMap);
            for (let [key, entry] of sorted) {
                let numberValue = entry.count;
                let labelValue = labelForLocation(key, entry.sourceCodeLocation);

                if (i === 0) {
                    this._observerHandlersNumberElement.textContent = numberValue;
                    this._observerHandlersLabelElement.append(labelValue);
                } else
                    this._insertTableRow(this._sourcesTable, this._sourcesRows, {headerValue, numberValue, labelValue});

                if (++i === sectionLimit && sorted.size > sectionLimit) {
                    this._insertTableRow(this._sourcesTable, this._sourcesRows, {labelValue: createEllipsisElement()});
                    break;
                }
            }
        }
    }

    _layoutEnergyChart(average, visibleDuration)
    {
        // The lower the bias value [0..1], the more it increases the skew towards rangeHigh.
        function mapWithBias(value, rangeLow, rangeHigh, outputRangeLow, outputRangeHigh, bias) {
            console.assert(value >= rangeLow && value <= rangeHigh, "value was not in range.", value);
            let percentInRange = (value - rangeLow) / (rangeHigh - rangeLow);
            let skewedPercent = Math.pow(percentInRange, bias);
            let valueInOutputRange = (skewedPercent * (outputRangeHigh - outputRangeLow)) + outputRangeLow;
            return valueInOutputRange;
        }

        this._clearEnergyImpactText();

        if (average === 0) {
             // Zero. (0% CPU, mapped to 0)
            this._energyImpactLabelElement.textContent = WI.UIString("Low");
            this._energyImpactLabelElement.classList.add("low");
            this._energyChart.value = 0;
        } else if (average <= CPUTimelineView.lowEnergyThreshold) {
            // Low. (<=3% CPU, mapped to 0-10)
            this._energyImpactLabelElement.textContent = WI.UIString("Low");
            this._energyImpactLabelElement.classList.add("low");
            this._energyChart.value = mapWithBias(average, 0, CPUTimelineView.lowEnergyThreshold, 0, CPUTimelineView.lowEnergyGraphBoundary, 0.85);
        } else if (average <= CPUTimelineView. mediumEnergyThreshold) {
            // Medium (3%-30% CPU, mapped to 10-70)
            this._energyImpactLabelElement.textContent = WI.UIString("Medium");
            this._energyImpactLabelElement.classList.add("medium");
            this._energyChart.value = mapWithBias(average, CPUTimelineView.lowEnergyThreshold, CPUTimelineView.mediumEnergyThreshold, CPUTimelineView.lowEnergyGraphBoundary, CPUTimelineView.mediumEnergyGraphBoundary, 0.6);
        } else if (average < CPUTimelineView. highEnergyThreshold) {
            // High. (30%-100% CPU, mapped to 70-100)
            this._energyImpactLabelElement.textContent = WI.UIString("High");
            this._energyImpactLabelElement.classList.add("high");
            this._energyChart.value = mapWithBias(average, CPUTimelineView.mediumEnergyThreshold, CPUTimelineView.highEnergyThreshold, CPUTimelineView.mediumEnergyGraphBoundary, CPUTimelineView.highEnergyGraphBoundary, 0.9);
        } else {
            // Very High. (>100% CPU, mapped to 100)
            this._energyImpactLabelElement.textContent = WI.UIString("Very High");
            this._energyImpactLabelElement.classList.add("high");
            this._energyChart.value = 100;
        }

        this._energyChart.needsLayout();

        this._energyImpactNumberElement.textContent = WI.UIString("Average CPU: %s").format(Number.percentageString(average / 100));

        if (visibleDuration < 5)
            this._energyImpactDurationElement.textContent = WI.UIString("Duration: Short");
        else {
            let durationDisplayString = Math.floor(visibleDuration);
            this._energyImpactDurationElement.textContent = WI.UIString("Duration: %ss", "The duration of the Timeline recording in seconds (s).").format(durationDisplayString);
        }
    }

    _computeStatisticsData(startTime, endTime)
    {
        // Compute per-millisecond samples of what the main thread was doing.
        // We construct an array for every millisecond between the start and end time
        // and mark each millisecond with the best representation of the work that
        // was being done at that time. We start by populating the samples with
        // all of the script periods and then override with layout and rendering
        // samples. This means a forced layout would be counted as a layout:
        //
        // Initial:        [ ------, ------, ------, ------, ------ ]
        // Script Samples: [ ------, Script, Script, Script, ------ ]
        // Layout Samples: [ ------, Script, Layout, Script, ------ ]
        //
        // The undefined samples are considered Idle, but in actuality WebKit
        // may have been doing some work (such as hit testing / inspector protocol)
        // that is not included it in generic Timeline data. This just works with
        // with the data available to the frontend and is quite accurate for most
        // Main Thread activity.

        function incrementTypeCount(map, key) {
            let entry = map.get(key);
            if (entry)
                map.set(key, entry + 1);
            else
                map.set(key, 1);
        }

        let timerInstallationRecords = [];
        let eventHandlerRecords = [];
        let observerCallbackRecords = [];
        let scriptEntries = 0;
        let timerTypes = new Map;
        let eventTypes = new Map;
        let observerTypes = new Map;

        let repeatingTimers = new Map;
        let possibleRepeatingTimers = new Set;

        let scriptTimeline = this._recording.timelineForRecordType(WI.TimelineRecord.Type.Script);
        let scriptRecords = scriptTimeline ? scriptTimeline.recordsInTimeRange(startTime, endTime, {includeRecordBeforeStart: true}) : [];
        scriptRecords = scriptRecords.filter((record) => {
            // Return true for event types that define script entries/exits.
            // Return false for events with no time ranges or if they are contained in other events.
            switch (record.eventType) {
            case WI.ScriptTimelineRecord.EventType.ScriptEvaluated:
            case WI.ScriptTimelineRecord.EventType.APIScriptEvaluated:
                scriptEntries++;
                return true;

            case WI.ScriptTimelineRecord.EventType.ObserverCallback:
                incrementTypeCount(observerTypes, record.details);
                observerCallbackRecords.push(record);
                scriptEntries++;
                return true;

            case WI.ScriptTimelineRecord.EventType.EventDispatched:
                incrementTypeCount(eventTypes, record.details);
                eventHandlerRecords.push(record);
                scriptEntries++;
                return true;

            case WI.ScriptTimelineRecord.EventType.MicrotaskDispatched:
                // Do not normally count this as a script entry, but they may have a time range
                // that is not covered by script entry (queueMicrotask).
                return true;

            case WI.ScriptTimelineRecord.EventType.TimerFired:
                incrementTypeCount(timerTypes, "setTimeout");
                if (possibleRepeatingTimers.has(record.details)) {
                    let entry = repeatingTimers.get(record.details);
                    if (entry)
                        entry.count += 1;
                    else
                        repeatingTimers.set(record.details, {record, count: 1});
                } else
                    possibleRepeatingTimers.add(record.details);
                scriptEntries++;
                return true;

            case WI.ScriptTimelineRecord.EventType.AnimationFrameFired:
                incrementTypeCount(timerTypes, "requestAnimationFrame");
                scriptEntries++;
                return true;

            case WI.ScriptTimelineRecord.EventType.AnimationFrameRequested:
            case WI.ScriptTimelineRecord.EventType.TimerInstalled:
                // These event types have no time range, or are contained by the others.
                timerInstallationRecords.push(record);
                return false;

            case WI.ScriptTimelineRecord.EventType.AnimationFrameCanceled:
            case WI.ScriptTimelineRecord.EventType.TimerRemoved:
            case WI.ScriptTimelineRecord.EventType.ProbeSampleRecorded:
            case WI.ScriptTimelineRecord.EventType.ConsoleProfileRecorded:
            case WI.ScriptTimelineRecord.EventType.GarbageCollected:
                // These event types have no time range, or are contained by the others.
                return false;

            default:
                console.error("Unhandled ScriptTimelineRecord.EventType", record.eventType);
                return false;
            }
        });

        let layoutTimeline = this._recording.timelineForRecordType(WI.TimelineRecord.Type.Layout);
        let layoutRecords = layoutTimeline ? layoutTimeline.recordsInTimeRange(startTime, endTime, {includeRecordBeforeStart: true}) : [];
        layoutRecords = layoutRecords.filter((record) => {
            switch (record.eventType) {
            case WI.LayoutTimelineRecord.EventType.RecalculateStyles:
            case WI.LayoutTimelineRecord.EventType.ForcedLayout:
            case WI.LayoutTimelineRecord.EventType.Layout:
            case WI.LayoutTimelineRecord.EventType.Paint:
            case WI.LayoutTimelineRecord.EventType.Composite:
                // These event types define layout and rendering entry/exits.
                return true;

            case WI.LayoutTimelineRecord.EventType.InvalidateStyles:
            case WI.LayoutTimelineRecord.EventType.InvalidateLayout:
                // These event types have no time range.
                return false;

            default:
                console.error("Unhandled LayoutTimelineRecord.EventType", record.eventType);
                return false;
            }
        });

        let networkTimeline = this._recording.timelineForRecordType(WI.TimelineRecord.Type.Network);
        let networkRecords = networkTimeline ? networkTimeline.recordsInTimeRange(startTime, endTime) : [];
        let networkRequests = networkRecords.length;

        let millisecondStartTime = Math.round(startTime * 1000);
        let millisecondEndTime = Math.round(endTime * 1000);
        let millisecondDuration = millisecondEndTime - millisecondStartTime;

        let samples = new Array(millisecondDuration);

        function markRecordEntries(records, callback) {
            for (let record of records) {
                let recordStart = Math.round(record.startTime * 1000);
                let recordEnd = Math.round(record.endTime * 1000);
                if (recordStart > millisecondEndTime)
                    continue;
                if (recordEnd < millisecondStartTime)
                    continue;

                recordStart = Math.max(recordStart, millisecondStartTime);
                recordEnd = Math.min(recordEnd, millisecondEndTime);

                let value = callback(record);
                for (let t = recordStart; t <= recordEnd; ++t)
                    samples[t - millisecondStartTime] = value;
            }
        }

        markRecordEntries(scriptRecords, (record) => {
            return CPUTimelineView.SampleType.JavaScript;
        });

        markRecordEntries(layoutRecords, (record) => {
            switch (record.eventType) {
            case WI.LayoutTimelineRecord.EventType.RecalculateStyles:
                return CPUTimelineView.SampleType.Style;
            case WI.LayoutTimelineRecord.EventType.ForcedLayout:
            case WI.LayoutTimelineRecord.EventType.Layout:
                return CPUTimelineView.SampleType.Layout;
            case WI.LayoutTimelineRecord.EventType.Paint:
            case WI.LayoutTimelineRecord.EventType.Composite:
                return CPUTimelineView.SampleType.Paint;
            }
        });

        let samplesIdle = 0;
        let samplesScript = 0;
        let samplesLayout = 0;
        let samplesPaint = 0;
        let samplesStyle = 0;
        for (let i = 0; i < samples.length; ++i) {
            switch (samples[i]) {
            case undefined:
                samplesIdle++;
                break;
            case CPUTimelineView.SampleType.JavaScript:
                samplesScript++;
                break;
            case CPUTimelineView.SampleType.Layout:
                samplesLayout++;
                break;
            case CPUTimelineView.SampleType.Paint:
                samplesPaint++;
                break;
            case CPUTimelineView.SampleType.Style:
                samplesStyle++;
                break;
            }
        }

        return {
            samples,
            samplesIdle,
            samplesScript,
            samplesLayout,
            samplesPaint,
            samplesStyle,
            scriptEntries,
            networkRequests,
            timerTypes,
            eventTypes,
            observerTypes,
            timerInstallationRecords,
            eventHandlerRecords,
            observerCallbackRecords,
            repeatingTimers,
        };
    }

    _removeWorkerThreadViews()
    {
        if (!this._workerViews.length)
            return;

        for (let view of this._workerViews)
            this.removeSubview(view);

        this._workerViews = [];
    }

    _resetSourcesFilters()
    {
        if (!this._sourcesFilter)
            return;

        this._sourcesFilterRow.hidden = true;
        this._sourcesFilterLabelElement.removeChildren();

        this._timerInstallationsRow.hidden = false;
        this._eventHandlersRow.hidden = false;
        this._observerHandlersRow.hidden = false;

        this._sourcesFilter.timer.clear();
        this._sourcesFilter.event.clear();
        this._sourcesFilter.observer.clear();
    }

    _addSourcesFilter(type, name)
    {
        this._sourcesFilter[type].add(name);
        this._updateSourcesFilters();
    }

    _removeSourcesFilter(type, name)
    {
        this._sourcesFilter[type].delete(name);
        this._updateSourcesFilters();
    }

    _updateSourcesFilters()
    {
        let timerFilters = this._sourcesFilter.timer;
        let eventFilters = this._sourcesFilter.event;
        let observerFilters = this._sourcesFilter.observer;

        if (!timerFilters.size && !eventFilters.size && !observerFilters.size) {
            this._resetSourcesFilters();
            return;
        }

        let createActiveFilterElement = (type, name) => {
            let span = document.createElement("span");
            span.className = "filter active";
            span.textContent = name;
            span.addEventListener("mouseup", (event) => {
                this._removeSourcesFilter(type, name);
                this._layoutStatisticsAndSources();
            });
            return span;
        };

        this._sourcesFilterRow.hidden = false;
        this._sourcesFilterLabelElement.removeChildren();

        for (let name of timerFilters)
            this._sourcesFilterLabelElement.appendChild(createActiveFilterElement("timer", name));
        for (let name of eventFilters)
            this._sourcesFilterLabelElement.appendChild(createActiveFilterElement("event", name));
        for (let name of observerFilters)
            this._sourcesFilterLabelElement.appendChild(createActiveFilterElement("observer", name));

        this._timerInstallationsRow.hidden = !timerFilters.size;
        this._eventHandlersRow.hidden = !eventFilters.size;
        this._observerHandlersRow.hidden = !observerFilters.size;
    }

    _createTableRow(table)
    {
        let row = table.appendChild(document.createElement("tr"));

        let headerCell = row.appendChild(document.createElement("th"));

        let numberCell = row.appendChild(document.createElement("td"));
        numberCell.className = "number";

        let labelCell = row.appendChild(document.createElement("td"));
        labelCell.className = "label";

        return {row, headerCell, numberCell, labelCell};
    }

    _insertTableRow(table, rowList, {headerValue, numberValue, labelValue, followingRow})
    {
        let {row, headerCell, numberCell, labelCell} = this._createTableRow(table);
        rowList.push(row);

        if (followingRow)
            table.insertBefore(row, followingRow);

        if (headerValue)
            headerCell.textContent = headerValue;

        if (numberValue)
            numberCell.textContent = numberValue;

        if (labelValue)
            labelCell.append(labelValue);

        return row;
    }

    _clearStatistics()
    {
        this._networkRequestsNumberElement.textContent = emDash;
        this._scriptEntriesNumberElement.textContent = emDash;

        for (let row of this._statisticsRows)
            row.remove();
        this._statisticsRows = [];
    }

    _clearSources()
    {
        this._timerInstallationsNumberElement.textContent = emDash;
        this._timerInstallationsLabelElement.textContent = "";

        this._eventHandlersNumberElement.textContent = emDash;
        this._eventHandlersLabelElement.textContent = "";

        this._observerHandlersNumberElement.textContent = emDash;
        this._observerHandlersLabelElement.textContent = "";

        for (let row of this._sourcesRows)
            row.remove();
        this._sourcesRows = [];
    }

    _clearEnergyImpactText()
    {
        this._energyImpactLabelElement.classList.remove("low", "medium", "high");
        this._energyImpactLabelElement.textContent = emDash;
        this._energyImpactNumberElement.textContent = "";
        this._energyImpactDurationElement.textContent = "";
    }

    _clearBreakdownLegend()
    {
        this._breakdownLegendScriptElement.textContent = emDash;
        this._breakdownLegendLayoutElement.textContent = emDash;
        this._breakdownLegendPaintElement.textContent = emDash;
        this._breakdownLegendStyleElement.textContent = emDash;

        this._breakdownChart.centerElement.removeChildren();
    }

    _cpuTimelineRecordAdded(event)
    {
        let cpuTimelineRecord = event.data.record;
        console.assert(cpuTimelineRecord instanceof WI.CPUTimelineRecord);

        if (cpuTimelineRecord.startTime >= this.startTime && cpuTimelineRecord.endTime <= this.endTime)
            this.needsLayout();
    }

    _graphPositionForMouseEvent(event)
    {
        let chartElement = event.target.closest(".area-chart, .stacked-area-chart, .range-chart");
        if (!chartElement)
            return NaN;

        let rect = chartElement.getBoundingClientRect();
        let position = event.pageX - rect.left;

        if (WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL)
            return rect.width - position;
        return position;
    }

    _handleIndicatorClick(event)
    {
        let clickPosition = this._graphPositionForMouseEvent(event);
        if (isNaN(clickPosition))
            return;

        let secondsPerPixel = this._timelineRuler.secondsPerPixel;
        let graphClickTime = clickPosition * secondsPerPixel;
        let graphStartTime = this.startTime;

        let clickStartTime = graphStartTime + graphClickTime;
        let clickEndTime = clickStartTime + secondsPerPixel;

        // Try at the exact clicked pixel.
        if (event.target.localName === "rect") {
            if (this._attemptSelectIndicatatorTimelineRecord(clickStartTime, clickEndTime))
                return;
            console.assert(false, "If the user clicked on a rect there should have been a record in this pixel range");
        }

        // Spiral out 4 pixels each side to try and select a nearby record.
        for (let i = 1, delta = 0; i <= 4; ++i) {
            delta += secondsPerPixel;
            if (this._attemptSelectIndicatatorTimelineRecord(clickStartTime - delta, clickStartTime))
                return;
            if (this._attemptSelectIndicatatorTimelineRecord(clickEndTime, clickEndTime + delta))
                return;
        }
    }

    _attemptSelectIndicatatorTimelineRecord(startTime, endTime)
    {
        let layoutTimeline = this._recording.timelineForRecordType(WI.TimelineRecord.Type.Layout);
        let layoutRecords = layoutTimeline ? layoutTimeline.recordsInTimeRange(startTime, endTime, {includeRecordBeforeStart: true}) : [];
        layoutRecords = layoutRecords.filter((record) => {
            switch (record.eventType) {
            case WI.LayoutTimelineRecord.EventType.RecalculateStyles:
            case WI.LayoutTimelineRecord.EventType.ForcedLayout:
            case WI.LayoutTimelineRecord.EventType.Layout:
            case WI.LayoutTimelineRecord.EventType.Paint:
            case WI.LayoutTimelineRecord.EventType.Composite:
                return true;
            case WI.LayoutTimelineRecord.EventType.InvalidateStyles:
            case WI.LayoutTimelineRecord.EventType.InvalidateLayout:
                return false;
            default:
                console.error("Unhandled LayoutTimelineRecord.EventType", record.eventType);
                return false;
            }
        });

        if (layoutRecords.length) {
            this._selectTimelineRecord(layoutRecords[0]);
            return true;
        }

        let scriptTimeline = this._recording.timelineForRecordType(WI.TimelineRecord.Type.Script);
        let scriptRecords = scriptTimeline ? scriptTimeline.recordsInTimeRange(startTime, endTime, {includeRecordBeforeStart: true}) : [];
        scriptRecords = scriptRecords.filter((record) => {
            switch (record.eventType) {
            case WI.ScriptTimelineRecord.EventType.ScriptEvaluated:
            case WI.ScriptTimelineRecord.EventType.APIScriptEvaluated:
            case WI.ScriptTimelineRecord.EventType.ObserverCallback:
            case WI.ScriptTimelineRecord.EventType.EventDispatched:
            case WI.ScriptTimelineRecord.EventType.MicrotaskDispatched:
            case WI.ScriptTimelineRecord.EventType.TimerFired:
            case WI.ScriptTimelineRecord.EventType.AnimationFrameFired:
                return true;
            case WI.ScriptTimelineRecord.EventType.AnimationFrameRequested:
            case WI.ScriptTimelineRecord.EventType.AnimationFrameCanceled:
            case WI.ScriptTimelineRecord.EventType.TimerInstalled:
            case WI.ScriptTimelineRecord.EventType.TimerRemoved:
            case WI.ScriptTimelineRecord.EventType.ProbeSampleRecorded:
            case WI.ScriptTimelineRecord.EventType.ConsoleProfileRecorded:
            case WI.ScriptTimelineRecord.EventType.GarbageCollected:
                return false;
            default:
                console.error("Unhandled ScriptTimelineRecord.EventType", record.eventType);
                return false;
            }
        });

        if (scriptRecords.length) {
            this._selectTimelineRecord(scriptRecords[0]);
            return true;
        }

        return false;
    }

    _selectTimelineRecord(record)
    {
        this.dispatchEventToListeners(WI.TimelineView.Event.RecordWasSelected, {record});
    }

    _handleGraphClick(event)
    {
        let mousePosition = this._graphPositionForMouseEvent(event);
        if (isNaN(mousePosition))
            return;

        this._stickingOverlay = !this._stickingOverlay;

        if (!this._stickingOverlay)
            this._handleGraphMouseMove(event);
    }

    _handleGraphMouseMove(event)
    {
        let mousePosition = this._graphPositionForMouseEvent(event);
        if (isNaN(mousePosition)) {
            this._hideGraphOverlay();
            this.dispatchEventToListeners(WI.TimelineView.Event.ScannerHide);
            return;
        }

        let secondsPerPixel = this._timelineRuler.secondsPerPixel;
        let time = this.startTime + (mousePosition * secondsPerPixel);

        if (!this._stickingOverlay)
            this._showGraphOverlayNearTo(time);

        this.dispatchEventToListeners(WI.TimelineView.Event.ScannerShow, {time});
    }

    _showGraphOverlayNearTo(time)
    {
        let nearestRecord = null;
        let nearestDistance = Infinity;

        // Find the nearest record to the time.
        for (let record of this._visibleRecordsInLayout) {
            let distance = Math.abs(time - record.timestamp);
            if (distance < nearestDistance) {
                nearestRecord = record;
                nearestDistance = distance;
            }
        }

        if (!nearestRecord) {
            this._hideGraphOverlay();
            return;
        }

        let bestTime = nearestRecord.timestamp;

        // Snap to a discontinuity if closer.
        for (let {startTime, endTime} of this._discontinuitiesInLayout) {
            let distance = Math.abs(time - startTime);
            if (distance < nearestDistance) {
                nearestDistance = distance;
                bestTime = startTime;
            }
            distance = Math.abs(time - endTime);
            if (distance < nearestDistance) {
                nearestDistance = distance;
                bestTime = endTime;
            }
        }

        // Snap to end time if closer.
        let visibleEndTime = Math.min(this.endTime, this.currentTime);
        let distance = Math.abs(time - visibleEndTime);
        if (distance < nearestDistance) {
            nearestDistance = distance;
            bestTime = visibleEndTime;
        }

        let graphStartTime = this.startTime;
        let adjustedTime = Number.constrain(bestTime, graphStartTime, visibleEndTime);
        this._showGraphOverlay(nearestRecord, adjustedTime);
    }

    _updateGraphOverlay()
    {
        if (!this._overlayRecord)
            return;

        this._showGraphOverlay(this._overlayRecord, this._overlayTime, true);
    }

    _showGraphOverlay(record, time, force)
    {
        if (!force && record === this._overlayRecord && time === this._overlayTime)
            return;

        this._overlayRecord = record;
        this._overlayTime = time;

        let secondsPerPixel = this._secondsPerPixelInLayout;
        let graphStartTime = this.startTime;

        this._overlayMarker.time = time + (secondsPerPixel / 2);

        function xScale(time) {
            return (time - graphStartTime) / secondsPerPixel;
        }

        let x = xScale(time);

        let {mainThreadUsage, workerThreadUsage, webkitThreadUsage, unknownThreadUsage, workersData} = record;

        function addOverlayPoint(view, graphHeight, layoutMax, value) {
            if (!value)
                return;

            let graphMax = layoutMax * 1.05;

            function yScale(value) {
                return graphHeight - ((value / graphMax) * graphHeight);
            }

            view.chart.addPointMarker(x, yScale(value));
            view.chart.needsLayout();
        }

        this._clearOverlayMarkers();

        this._cpuUsageView.updateLegend(record);
        addOverlayPoint(this._cpuUsageView, CPUTimelineView.cpuUsageViewHeight, this._layoutMax, mainThreadUsage);
        addOverlayPoint(this._cpuUsageView, CPUTimelineView.cpuUsageViewHeight, this._layoutMax, mainThreadUsage + workerThreadUsage);
        addOverlayPoint(this._cpuUsageView, CPUTimelineView.cpuUsageViewHeight, this._layoutMax, mainThreadUsage + workerThreadUsage + webkitThreadUsage + unknownThreadUsage);

        if (this._threadsDetailsElement.open) {
            this._mainThreadUsageView.updateLegend(mainThreadUsage);
            addOverlayPoint(this._mainThreadUsageView, CPUTimelineView.threadCPUUsageViewHeight, this._threadLayoutMax, mainThreadUsage);

            this._webkitThreadUsageView.updateLegend(webkitThreadUsage);
            addOverlayPoint(this._webkitThreadUsageView, CPUTimelineView.threadCPUUsageViewHeight, this._threadLayoutMax, webkitThreadUsage);

            this._unknownThreadUsageView.updateLegend(unknownThreadUsage);
            addOverlayPoint(this._unknownThreadUsageView, CPUTimelineView.threadCPUUsageViewHeight, this._threadLayoutMax, unknownThreadUsage);

            for (let workerView of this._workerViews)
                workerView.updateLegend(NaN);

            if (workersData) {
                for (let {targetId, usage} of workersData) {
                    let workerView = this._workerViews.find((x) => x.__workerId === targetId);
                    if (workerView) {
                        workerView.updateLegend(usage);
                        addOverlayPoint(workerView, CPUTimelineView.threadCPUUsageViewHeight, this._threadLayoutMax, usage);
                    }
                }
            }
        }
    }

    _clearOverlayMarkers()
    {
        function clearGraphOverlayElement(view) {
            view.clearLegend();
            view.chart.clearPointMarkers();
            view.chart.needsLayout();
        }

        clearGraphOverlayElement(this._cpuUsageView);
        clearGraphOverlayElement(this._mainThreadUsageView);
        clearGraphOverlayElement(this._webkitThreadUsageView);
        clearGraphOverlayElement(this._unknownThreadUsageView);

        for (let workerView of this._workerViews)
            clearGraphOverlayElement(workerView);
    }

    _hideGraphOverlay()
    {
        if (this._stickingOverlay)
            return;

        this._overlayRecord = null;
        this._overlayTime = NaN;
        this._overlayMarker.time = -1;
        this._clearOverlayMarkers();
    }
};

WI.CPUTimelineView.LayoutReason = {
    Internal: Symbol("cpu-timeline-view-internal-layout"),
};

// NOTE: UI follows this order.
WI.CPUTimelineView.SampleType = {
    JavaScript: "sample-type-javascript",
    Layout: "sample-type-layout",
    Paint: "sample-type-paint",
    Style: "sample-type-style",
};
