/*
 * 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.startTime;
            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;

                let offset = recordStart - millisecondStartTime;
                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",
};
