/*
 * Copyright (C) 2013, 2016 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.
 */

// FIXME: TimelineManager lacks advanced multi-target support. (Instruments/Profilers per-target)

WI.TimelineManager = class TimelineManager extends WI.Object
{
    constructor()
    {
        super();

        this._enabled = false;

        WI.Frame.addEventListener(WI.Frame.Event.ProvisionalLoadStarted, this._provisionalLoadStarted, this);
        WI.Frame.addEventListener(WI.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this);

        this._enabledTimelineTypesSetting = new WI.Setting("enabled-instrument-types", WI.TimelineManager.defaultTimelineTypes());

        this._capturingState = TimelineManager.CapturingState.Inactive;
        this._capturingInstrumentCount = 0;
        this._capturingStartTime = NaN;
        this._capturingEndTime = NaN;

        this._initiatedByBackendStart = false;
        this._initiatedByBackendStop = false;

        this._isCapturingPageReload = false;
        this._autoCaptureOnPageLoad = false;
        this._mainResourceForAutoCapturing = null;
        this._shouldSetAutoCapturingMainResource = false;
        this._transitioningPageTarget = false;

        this._webTimelineScriptRecordsExpectingScriptProfilerEvents = null;
        this._scriptProfilerRecords = null;

        this._boundStopCapturing = this.stopCapturing.bind(this);
        this._stopCapturingTimeout = undefined;
        this._deadTimeTimeout = undefined;
        this._lastDeadTimeTickle = 0;

        this.reset();
    }

    // Agent

    get domains() { return ["Timeline"]; }

    activateExtraDomain(domain)
    {
        console.assert(domain === "Timeline");

        for (let target of WI.targets)
            this.initializeTarget(target);
    }

    // Target

    initializeTarget(target)
    {
        if (!this._enabled)
            return;

        if (target.hasDomain("Timeline")) {
            // COMPATIBILITY (iOS 13): Timeline.enable did not exist yet.
            if (target.hasCommand("Timeline.enable"))
                target.TimelineAgent.enable();

            this._updateAutoCaptureInstruments([target]);

            // COMPATIBILITY (iOS 9): Timeline.setAutoCaptureEnabled did not exist.
            if (target.hasCommand("Timeline.setAutoCaptureEnabled"))
                target.TimelineAgent.setAutoCaptureEnabled(this._autoCaptureOnPageLoad);
        }
    }

    transitionPageTarget()
    {
        this._transitioningPageTarget = true;
    }

    // Static

    static defaultTimelineTypes()
    {
        if (WI.sharedApp.debuggableType === WI.DebuggableType.JavaScript) {
            let defaultTypes = [WI.TimelineRecord.Type.Script];
            if (WI.HeapAllocationsInstrument.supported())
                defaultTypes.push(WI.TimelineRecord.Type.HeapAllocations);
            return defaultTypes;
        }

        if (WI.sharedApp.debuggableType === WI.DebuggableType.ServiceWorker) {
            // FIXME: Support Network Timeline in ServiceWorker.
            let defaultTypes = [WI.TimelineRecord.Type.Script];
            if (WI.HeapAllocationsInstrument.supported())
                defaultTypes.push(WI.TimelineRecord.Type.HeapAllocations);
            return defaultTypes;
        }

        let defaultTypes = [
            WI.TimelineRecord.Type.Network,
            WI.TimelineRecord.Type.Layout,
            WI.TimelineRecord.Type.Script,
        ];

        if (WI.CPUInstrument.supported())
            defaultTypes.push(WI.TimelineRecord.Type.CPU);

        if (WI.FPSInstrument.supported())
            defaultTypes.push(WI.TimelineRecord.Type.RenderingFrame);

        return defaultTypes;
    }

    static availableTimelineTypes()
    {
        let types = WI.TimelineManager.defaultTimelineTypes();
        if (WI.sharedApp.debuggableType === WI.DebuggableType.JavaScript || WI.sharedApp.debuggableType === WI.DebuggableType.ServiceWorker)
            return types;

        if (WI.MemoryInstrument.supported())
            types.push(WI.TimelineRecord.Type.Memory);

        if (WI.HeapAllocationsInstrument.supported())
            types.push(WI.TimelineRecord.Type.HeapAllocations);

        if (WI.MediaInstrument.supported()) {
            let insertionIndex = types.indexOf(WI.TimelineRecord.Type.Layout) + 1;
            types.insertAtIndex(WI.TimelineRecord.Type.Media, insertionIndex || types.length);
        }

        return types;
    }

    static synthesizeImportError(message)
    {
        message = WI.UIString("Timeline Recording Import Error: %s").format(message);

        if (window.InspectorTest) {
            console.error(message);
            return;
        }

        let consoleMessage = new WI.ConsoleMessage(WI.mainTarget, WI.ConsoleMessage.MessageSource.Other, WI.ConsoleMessage.MessageLevel.Error, message);
        consoleMessage.shouldRevealConsole = true;

        WI.consoleLogViewController.appendConsoleMessage(consoleMessage);
    }

    // Public

    get capturingState() { return this._capturingState; }

    reset()
    {
        if (this._capturingState === TimelineManager.CapturingState.Starting || this._capturingState === TimelineManager.CapturingState.Active)
            this.stopCapturing();

        this._recordings = [];
        this._activeRecording = null;
        this._nextRecordingIdentifier = 1;

        this._loadNewRecording();
    }

    // The current recording that new timeline records will be appended to, if any.
    get activeRecording()
    {
        console.assert(this._activeRecording || !this.isCapturing());
        return this._activeRecording;
    }

    get recordings()
    {
        return this._recordings.slice();
    }

    get autoCaptureOnPageLoad()
    {
        return this._autoCaptureOnPageLoad;
    }

    set autoCaptureOnPageLoad(autoCapture)
    {
        console.assert(this._enabled);

        autoCapture = !!autoCapture;

        if (this._autoCaptureOnPageLoad === autoCapture)
            return;

        this._autoCaptureOnPageLoad = autoCapture;

        for (let target of WI.targets) {
            // COMPATIBILITY (iOS 9): Timeline.setAutoCaptureEnabled did not exist yet.
            if (target.hasCommand("Timeline.setAutoCaptureEnabled"))
                target.TimelineAgent.setAutoCaptureEnabled(this._autoCaptureOnPageLoad);
        }
    }

    get enabledTimelineTypes()
    {
        let availableTimelineTypes = WI.TimelineManager.availableTimelineTypes();
        return this._enabledTimelineTypesSetting.value.filter((type) => availableTimelineTypes.includes(type));
    }

    set enabledTimelineTypes(x)
    {
        this._enabledTimelineTypesSetting.value = x || [];

        this._updateAutoCaptureInstruments(WI.targets);
    }

    isCapturing()
    {
        return this._capturingState !== TimelineManager.CapturingState.Inactive;
    }

    isCapturingPageReload()
    {
        return this._isCapturingPageReload;
    }

    willAutoStop()
    {
        return !!this._stopCapturingTimeout;
    }

    relaxAutoStop()
    {
        if (this._stopCapturingTimeout) {
            clearTimeout(this._stopCapturingTimeout);
            this._stopCapturingTimeout = undefined;
        }

        if (this._deadTimeTimeout) {
            clearTimeout(this._deadTimeTimeout);
            this._deadTimeTimeout = undefined;
        }
    }

    enable()
    {
        if (this._enabled)
            return;

        this._enabled = true;

        this.reset();

        for (let target of WI.targets)
            this.initializeTarget(target);
    }

    disable()
    {
        if (!this._enabled)
            return;

        this.reset();

        for (let target of WI.targets) {
            // COMPATIBILITY (iOS 13): Timeline.disable did not exist yet.
            if (target.hasCommand("Timeline.disable"))
                target.TimelineAgent.disable();
        }

        this._enabled = false;
    }

    startCapturing(shouldCreateRecording)
    {
        console.assert(this._enabled);

        console.assert(this._capturingState === TimelineManager.CapturingState.Stopping || this._capturingState === TimelineManager.CapturingState.Inactive, "TimelineManager is already capturing.");
        if (this._capturingState !== TimelineManager.CapturingState.Stopping && this._capturingState !== TimelineManager.CapturingState.Inactive)
            return;

        if (!this._activeRecording || shouldCreateRecording)
            this._loadNewRecording();

        this._updateCapturingState(TimelineManager.CapturingState.Starting);

        this._capturingStartTime = NaN;
        this._activeRecording.start(this._initiatedByBackendStart);
    }

    stopCapturing()
    {
        console.assert(this._enabled);

        console.assert(this._capturingState === TimelineManager.CapturingState.Starting || this._capturingState === TimelineManager.CapturingState.Active, "TimelineManager is not capturing.");
        if (this._capturingState !== TimelineManager.CapturingState.Starting && this._capturingState !== TimelineManager.CapturingState.Active)
            return;

        this._updateCapturingState(TimelineManager.CapturingState.Stopping);

        this._capturingEndTime = NaN;
        this._activeRecording.stop(this._initiatedByBackendStop);
    }

    async processJSON({filename, json, error})
    {
        if (error) {
            WI.TimelineManager.synthesizeImportError(error);
            return;
        }

        if (typeof json !== "object" || json === null) {
            WI.TimelineManager.synthesizeImportError(WI.UIString("invalid JSON"));
            return;
        }

        if (!json.recording || typeof json.recording !== "object" || !json.overview || typeof json.overview !== "object" || typeof json.version !== "number") {
            WI.TimelineManager.synthesizeImportError(WI.UIString("invalid JSON"));
            return;
        }

        if (json.version !== WI.TimelineRecording.SerializationVersion) {
            WI.NetworkManager.synthesizeImportError(WI.UIString("unsupported version"));
            return;
        }

        let recordingData = json.recording;
        let overviewData = json.overview;

        let identifier = this._nextRecordingIdentifier++;
        let newRecording = await WI.TimelineRecording.import(identifier, recordingData, filename);
        this._recordings.push(newRecording);

        this.dispatchEventToListeners(WI.TimelineManager.Event.RecordingCreated, {recording: newRecording});

        if (this._capturingState === TimelineManager.CapturingState.Starting || this._capturingState === TimelineManager.CapturingState.Active)
            this.stopCapturing();

        let oldRecording = this._activeRecording;
        if (oldRecording) {
            const importing = true;
            oldRecording.unloaded(importing);
        }

        this._activeRecording = newRecording;

        this.dispatchEventToListeners(WI.TimelineManager.Event.RecordingLoaded, {oldRecording});
        this.dispatchEventToListeners(WI.TimelineManager.Event.RecordingImported, {overviewData});
    }

    computeElapsedTime(timestamp)
    {
        if (!this._activeRecording)
            return 0;

        return this._activeRecording.computeElapsedTime(timestamp);
    }

    scriptProfilerIsTracking()
    {
        return this._scriptProfilerRecords !== null;
    }

    // ConsoleObserver

    heapSnapshotAdded(timestamp, snapshot)
    {
        if (!this._enabled)
            return;

        this._addRecord(new WI.HeapAllocationsTimelineRecord(timestamp, snapshot));
    }

    // TimelineObserver

    capturingStarted(startTime)
    {
        // The frontend didn't start capturing, so this was a programmatic start.
        if (this._capturingState === TimelineManager.CapturingState.Inactive) {
            this._initiatedByBackendStart = true;
            this._activeRecording.addScriptInstrumentForProgrammaticCapture();
            this.startCapturing();
        }

        if (!isNaN(startTime)) {
            if (isNaN(this._capturingStartTime) || startTime < this._capturingStartTime)
                this._capturingStartTime = startTime;

            this._activeRecording.initializeTimeBoundsIfNecessary(startTime);
        }

        this._capturingInstrumentCount++;
        console.assert(this._capturingInstrumentCount);
        if (this._capturingInstrumentCount > 1)
            return;

        if (this._capturingState === TimelineManager.CapturingState.Active)
            return;

        this._lastDeadTimeTickle = 0;

        this._webTimelineScriptRecordsExpectingScriptProfilerEvents = [];

        this._activeRecording.capturingStarted(this._capturingStartTime);

        WI.settings.timelinesAutoStop.addEventListener(WI.Setting.Event.Changed, this._handleTimelinesAutoStopSettingChanged, this);

        WI.Frame.addEventListener(WI.Frame.Event.ResourceWasAdded, this._resourceWasAdded, this);
        WI.Target.addEventListener(WI.Target.Event.ResourceAdded, this._resourceWasAdded, this);

        WI.heapManager.addEventListener(WI.HeapManager.Event.GarbageCollected, this._garbageCollected, this);

        WI.memoryManager.addEventListener(WI.MemoryManager.Event.MemoryPressure, this._memoryPressure, this);

        WI.DOMNode.addEventListener(WI.DOMNode.Event.DidFireEvent, this._handleDOMNodeDidFireEvent, this);
        WI.DOMNode.addEventListener(WI.DOMNode.Event.PowerEfficientPlaybackStateChanged, this._handleDOMNodePowerEfficientPlaybackStateChanged, this);

        this._updateCapturingState(TimelineManager.CapturingState.Active, {startTime: this._capturingStartTime});
    }

    capturingStopped(endTime)
    {
        // The frontend didn't stop capturing, so this was a programmatic stop.
        if (this._capturingState === TimelineManager.CapturingState.Active) {
            this._initiatedByBackendStop = true;
            this.stopCapturing();
        }

        if (!isNaN(endTime)) {
            if (isNaN(this._capturingEndTime) || endTime > this._capturingEndTime)
                this._capturingEndTime = endTime;
        }

        this._capturingInstrumentCount--;
        console.assert(this._capturingInstrumentCount >= 0);
        if (this._capturingInstrumentCount)
            return;

        if (this._capturingState === TimelineManager.CapturingState.Inactive)
            return;

        WI.DOMNode.removeEventListener(null, null, this);
        WI.memoryManager.removeEventListener(null, null, this);
        WI.heapManager.removeEventListener(null, null, this);
        WI.Target.removeEventListener(WI.Target.Event.ResourceAdded, this._resourceWasAdded, this);
        WI.Frame.removeEventListener(WI.Frame.Event.ResourceWasAdded, this._resourceWasAdded, this);
        WI.settings.timelinesAutoStop.removeEventListener(null, null, this);

        this._activeRecording.capturingStopped(this._capturingEndTime);

        this.relaxAutoStop();

        this._isCapturingPageReload = false;
        this._shouldSetAutoCapturingMainResource = false;
        this._mainResourceForAutoCapturing = null;
        this._initiatedByBackendStart = false;
        this._initiatedByBackendStop = false;

        this._updateCapturingState(TimelineManager.CapturingState.Inactive, {endTime: this._capturingEndTime});
    }

    autoCaptureStarted()
    {
        console.assert(this._enabled);

        let waitingForCapturingStartedEvent = this._capturingState === TimelineManager.CapturingState.Starting;

        if (this._capturingState === TimelineManager.CapturingState.Starting || this._capturingState === TimelineManager.CapturingState.Active)
            this.stopCapturing();

        this._initiatedByBackendStart = true;

        // We may already have an fresh TimelineRecording created if autoCaptureStarted is received
        // between sending the Timeline.start command and receiving Timeline.capturingStarted event.
        // In that case, there is no need to call startCapturing again. Reuse the fresh recording.
        if (!waitingForCapturingStartedEvent) {
            const createNewRecording = true;
            this.startCapturing(createNewRecording);
        }

        this._shouldSetAutoCapturingMainResource = true;
    }

    eventRecorded(recordPayload)
    {
        if (!this._enabled)
            return;

        console.assert(this.isCapturing());
        if (!this.isCapturing())
            return;

        var records = [];

        // Iterate over the records tree using a stack. Doing this recursively has
        // been known to cause a call stack overflow. https://webkit.org/b/79106
        var stack = [{array: [recordPayload], parent: null, parentRecord: null, index: 0}];
        while (stack.length) {
            var entry = stack.lastValue;
            var recordPayloads = entry.array;

            if (entry.index < recordPayloads.length) {
                var recordPayload = recordPayloads[entry.index];
                var record = this._processEvent(recordPayload, entry.parent);
                if (record) {
                    record.parent = entry.parentRecord;
                    records.push(record);
                    if (entry.parentRecord)
                        entry.parentRecord.children.push(record);
                }

                if (recordPayload.children && recordPayload.children.length)
                    stack.push({array: recordPayload.children, parent: recordPayload, parentRecord: record || entry.parentRecord, index: 0});
                ++entry.index;
            } else
                stack.pop();
        }

        for (var record of records) {
            if (record.type === WI.TimelineRecord.Type.RenderingFrame) {
                if (!record.children.length)
                    continue;
                record.setupFrameIndex();
            }

            this._addRecord(record);
        }
    }

    // PageObserver

    pageDOMContentLoadedEventFired(timestamp)
    {
        if (!this._enabled)
            return;

        console.assert(this._activeRecording);

        let computedTimestamp = this._activeRecording.computeElapsedTime(timestamp);

        if (WI.networkManager.mainFrame)
            WI.networkManager.mainFrame.markDOMContentReadyEvent(computedTimestamp);

        let eventMarker = new WI.TimelineMarker(computedTimestamp, WI.TimelineMarker.Type.DOMContentEvent);
        this._activeRecording.addEventMarker(eventMarker);
    }

    pageLoadEventFired(timestamp)
    {
        if (!this._enabled)
            return;

        console.assert(this._activeRecording);

        let computedTimestamp = this._activeRecording.computeElapsedTime(timestamp);

        if (WI.networkManager.mainFrame)
            WI.networkManager.mainFrame.markLoadEvent(computedTimestamp);

        let eventMarker = new WI.TimelineMarker(computedTimestamp, WI.TimelineMarker.Type.LoadEvent);
        this._activeRecording.addEventMarker(eventMarker);

        this._stopAutoRecordingSoon();
    }

    // CPUProfilerObserver

    cpuProfilerTrackingStarted(timestamp)
    {
        this.capturingStarted(timestamp);
    }

    cpuProfilerTrackingUpdated(event)
    {
        if (!this._enabled)
            return;

        console.assert(this.isCapturing());
        if (!this.isCapturing())
            return;

        this._addRecord(new WI.CPUTimelineRecord(event));
    }

    cpuProfilerTrackingCompleted(timestamp)
    {
        this.capturingStopped(timestamp);
    }

    // ScriptProfilerObserver

    scriptProfilerTrackingStarted(timestamp)
    {
        this._scriptProfilerRecords = [];

        this.capturingStarted(timestamp);
    }

    scriptProfilerTrackingUpdated(event)
    {
        if (!this._enabled)
            return;

        let {startTime, endTime, type} = event;
        let scriptRecordType = this._scriptProfilerTypeToScriptTimelineRecordType(type);
        let record = new WI.ScriptTimelineRecord(scriptRecordType, startTime, endTime, null, null, null, null);
        record.__scriptProfilerType = type;
        this._scriptProfilerRecords.push(record);

        // "Other" events, generated by Web content, will have wrapping Timeline records
        // and need to be merged. Non-Other events, generated purely by the JavaScript
        // engine or outside of the page via APIs, will not have wrapping Timeline
        // records, so these records can just be added right now.
        if (type !== InspectorBackend.Enum.ScriptProfiler.EventType.Other)
            this._addRecord(record);
    }

    scriptProfilerTrackingCompleted(timestamp, samples)
    {
        if (this._enabled) {
            console.assert(!this._webTimelineScriptRecordsExpectingScriptProfilerEvents || this._scriptProfilerRecords.length >= this._webTimelineScriptRecordsExpectingScriptProfilerEvents.length);

            if (samples) {
                let {stackTraces} = samples;
                let topDownCallingContextTree = this._activeRecording.topDownCallingContextTree;

                // Calculate a per-sample duration.
                let timestampIndex = 0;
                let timestampCount = stackTraces.length;
                let sampleDurations = new Array(timestampCount);
                let sampleDurationIndex = 0;
                const defaultDuration = 1 / 1000; // 1ms.
                for (let i = 0; i < this._scriptProfilerRecords.length; ++i) {
                    let record = this._scriptProfilerRecords[i];

                    // Use a default duration for timestamps recorded outside of ScriptProfiler events.
                    while (timestampIndex < timestampCount && stackTraces[timestampIndex].timestamp < record.startTime) {
                        sampleDurations[sampleDurationIndex++] = defaultDuration;
                        timestampIndex++;
                    }

                    // Average the duration per sample across all samples during the record.
                    let samplesInRecord = 0;
                    while (timestampIndex < timestampCount && stackTraces[timestampIndex].timestamp < record.endTime) {
                        timestampIndex++;
                        samplesInRecord++;
                    }
                    if (samplesInRecord) {
                        let averageDuration = (record.endTime - record.startTime) / samplesInRecord;
                        sampleDurations.fill(averageDuration, sampleDurationIndex, sampleDurationIndex + samplesInRecord);
                        sampleDurationIndex += samplesInRecord;
                    }
                }

                // Use a default duration for timestamps recorded outside of ScriptProfiler events.
                if (timestampIndex < timestampCount)
                    sampleDurations.fill(defaultDuration, sampleDurationIndex);

                this._activeRecording.initializeCallingContextTrees(stackTraces, sampleDurations);

                // FIXME: This transformation should not be needed after introducing ProfileView.
                // Once we eliminate ProfileNodeTreeElements and ProfileNodeDataGridNodes.
                // <https://webkit.org/b/154973> Web Inspector: Timelines UI redesign: Remove TimelineSidebarPanel
                for (let i = 0; i < this._scriptProfilerRecords.length; ++i) {
                    let record = this._scriptProfilerRecords[i];
                    record.profilePayload = topDownCallingContextTree.toCPUProfilePayload(record.startTime, record.endTime);
                }
            }

            // Associate the ScriptProfiler created records with Web Timeline records.
            // Filter out the already added ScriptProfiler events which should not have been wrapped.
            if (WI.sharedApp.debuggableType !== WI.DebuggableType.JavaScript) {
                this._scriptProfilerRecords = this._scriptProfilerRecords.filter((x) => x.__scriptProfilerType === InspectorBackend.Enum.ScriptProfiler.EventType.Other);
                this._mergeScriptProfileRecords();
            }

            this._scriptProfilerRecords = null;

            let timeline = this._activeRecording.timelineForRecordType(WI.TimelineRecord.Type.Script);
            timeline.refresh();
        }

        this.capturingStopped(timestamp);
    }

    // MemoryObserver

    memoryTrackingStarted(timestamp)
    {
        this.capturingStarted(timestamp);
    }

    memoryTrackingUpdated(event)
    {
        if (!this._enabled)
            return;

        console.assert(this.isCapturing());
        if (!this.isCapturing())
            return;

        this._addRecord(new WI.MemoryTimelineRecord(event.timestamp, event.categories));
    }

    memoryTrackingCompleted(timestamp)
    {
        this.capturingStopped(timestamp);
    }

    // HeapObserver

    heapTrackingStarted(timestamp, snapshot)
    {
        this.capturingStarted(timestamp);

        if (this._enabled)
            this._addRecord(new WI.HeapAllocationsTimelineRecord(timestamp, snapshot));
    }

    heapTrackingCompleted(timestamp, snapshot)
    {
        if (this._enabled)
            this._addRecord(new WI.HeapAllocationsTimelineRecord(timestamp, snapshot));

        this.capturingStopped();
    }

    // AnimationObserver

    animationTrackingStarted(timestamp)
    {
        this.capturingStarted(timestamp);
    }

    animationTrackingUpdated(timestamp, event)
    {
        if (!this._enabled)
            return;

        console.assert(this.isCapturing());
        if (!this.isCapturing())
            return;

        let mediaTimeline = this._activeRecording.timelineForRecordType(WI.TimelineRecord.Type.Media);
        console.assert(mediaTimeline);

        let record = mediaTimeline.recordForTrackingAnimationId(event.trackingAnimationId);
        if (!record) {
            let details = {
                trackingAnimationId: event.trackingAnimationId,
            };

            let eventType;
            if (event.animationName) {
                eventType = WI.MediaTimelineRecord.EventType.CSSAnimation;
                details.animationName = event.animationName;
            } else if (event.transitionProperty) {
                eventType = WI.MediaTimelineRecord.EventType.CSSTransition;
                details.transitionProperty = event.transitionProperty;
            } else {
                WI.reportInternalError(`Unknown event type for event '${JSON.stringify(event)}'`);
                return;
            }

            let domNode = WI.domManager.nodeForId(event.nodeId);
            console.assert(domNode);

            record = new WI.MediaTimelineRecord(eventType, domNode, details);
            this._addRecord(record);
        }

        record.updateAnimationState(timestamp, event.animationState);
    }

    animationTrackingCompleted(timestamp)
    {
        this.capturingStopped(timestamp);
    }

    // Private

    _updateCapturingState(state, data = {})
    {
        if (this._capturingState === state)
            return;

        this._capturingState = state;

        this.dispatchEventToListeners(TimelineManager.Event.CapturingStateChanged, data);
    }

    _processRecord(recordPayload, parentRecordPayload)
    {
        console.assert(this.isCapturing());

        var startTime = this._activeRecording.computeElapsedTime(recordPayload.startTime);
        var endTime = this._activeRecording.computeElapsedTime(recordPayload.endTime);
        var callFrames = this._callFramesFromPayload(recordPayload.stackTrace);

        var significantCallFrame = null;
        if (callFrames) {
            for (var i = 0; i < callFrames.length; ++i) {
                if (callFrames[i].nativeCode)
                    continue;
                significantCallFrame = callFrames[i];
                break;
            }
        }

        var sourceCodeLocation = significantCallFrame && significantCallFrame.sourceCodeLocation;

        switch (recordPayload.type) {
        case InspectorBackend.Enum.Timeline.EventType.ScheduleStyleRecalculation:
            console.assert(isNaN(endTime));

            // Pass the startTime as the endTime since this record type has no duration.
            return new WI.LayoutTimelineRecord(WI.LayoutTimelineRecord.EventType.InvalidateStyles, startTime, startTime, callFrames, sourceCodeLocation);

        case InspectorBackend.Enum.Timeline.EventType.RecalculateStyles:
            return new WI.LayoutTimelineRecord(WI.LayoutTimelineRecord.EventType.RecalculateStyles, startTime, endTime, callFrames, sourceCodeLocation);

        case InspectorBackend.Enum.Timeline.EventType.InvalidateLayout:
            console.assert(isNaN(endTime));

            // Pass the startTime as the endTime since this record type has no duration.
            return new WI.LayoutTimelineRecord(WI.LayoutTimelineRecord.EventType.InvalidateLayout, startTime, startTime, callFrames, sourceCodeLocation);

        case InspectorBackend.Enum.Timeline.EventType.Layout:
            var layoutRecordType = sourceCodeLocation ? WI.LayoutTimelineRecord.EventType.ForcedLayout : WI.LayoutTimelineRecord.EventType.Layout;
            var quad = new WI.Quad(recordPayload.data.root);
            return new WI.LayoutTimelineRecord(layoutRecordType, startTime, endTime, callFrames, sourceCodeLocation, quad);

        case InspectorBackend.Enum.Timeline.EventType.Paint:
            var quad = new WI.Quad(recordPayload.data.clip);
            return new WI.LayoutTimelineRecord(WI.LayoutTimelineRecord.EventType.Paint, startTime, endTime, callFrames, sourceCodeLocation, quad);

        case InspectorBackend.Enum.Timeline.EventType.Composite:
            return new WI.LayoutTimelineRecord(WI.LayoutTimelineRecord.EventType.Composite, startTime, endTime, callFrames, sourceCodeLocation);

        case InspectorBackend.Enum.Timeline.EventType.RenderingFrame:
            if (!recordPayload.children || !recordPayload.children.length)
                return null;

            return new WI.RenderingFrameTimelineRecord(startTime, endTime);

        case InspectorBackend.Enum.Timeline.EventType.EvaluateScript:
            if (!sourceCodeLocation) {
                var mainFrame = WI.networkManager.mainFrame;
                var scriptResource = mainFrame.url === recordPayload.data.url ? mainFrame.mainResource : mainFrame.resourceForURL(recordPayload.data.url, true);
                if (scriptResource) {
                    // The lineNumber is 1-based, but we expect 0-based.
                    let lineNumber = recordPayload.data.lineNumber - 1;
                    let columnNumber = "columnNumber" in recordPayload.data ? recordPayload.data.columnNumber - 1 : 0;
                    sourceCodeLocation = scriptResource.createSourceCodeLocation(lineNumber, columnNumber);
                }
            }

            var profileData = recordPayload.data.profile;

            var record;
            switch (parentRecordPayload && parentRecordPayload.type) {
            case InspectorBackend.Enum.Timeline.EventType.TimerFire:
                record = new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.TimerFired, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.timerId, profileData);
                break;
            case InspectorBackend.Enum.Timeline.EventType.ObserverCallback:
                record = new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.ObserverCallback, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.type, profileData);
                break;
            case InspectorBackend.Enum.Timeline.EventType.FireAnimationFrame:
                record = new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.AnimationFrameFired, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.id, profileData);
                break;
            default:
                record = new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.ScriptEvaluated, startTime, endTime, callFrames, sourceCodeLocation, null, profileData);
                break;
            }

            this._webTimelineScriptRecordsExpectingScriptProfilerEvents.push(record);
            return record;

        case InspectorBackend.Enum.Timeline.EventType.ConsoleProfile:
            var profileData = recordPayload.data.profile;
            // COMPATIBILITY (iOS 9): With the Sampling Profiler, profiles no longer include legacy profile data.
            console.assert(profileData || InspectorBackend.hasCommand("Timeline.setInstruments"));
            return new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.ConsoleProfileRecorded, startTime, endTime, callFrames, sourceCodeLocation, recordPayload.data.title, profileData);

        case InspectorBackend.Enum.Timeline.EventType.TimerFire:
        case InspectorBackend.Enum.Timeline.EventType.EventDispatch:
        case InspectorBackend.Enum.Timeline.EventType.FireAnimationFrame:
        case InspectorBackend.Enum.Timeline.EventType.ObserverCallback:
            // These are handled when we see the child FunctionCall or EvaluateScript.
            break;

        case InspectorBackend.Enum.Timeline.EventType.FunctionCall:
            // FunctionCall always happens as a child of another record, and since the FunctionCall record
            // has useful info we just make the timeline record here (combining the data from both records).
            if (!parentRecordPayload) {
                console.warn("Unexpectedly received a FunctionCall timeline record without a parent record");
                break;
            }

            if (!sourceCodeLocation) {
                var mainFrame = WI.networkManager.mainFrame;
                var scriptResource = mainFrame.url === recordPayload.data.scriptName ? mainFrame.mainResource : mainFrame.resourceForURL(recordPayload.data.scriptName, true);
                if (scriptResource) {
                    // The lineNumber is 1-based, but we expect 0-based.
                    let lineNumber = recordPayload.data.scriptLine - 1;
                    let columnNumber = "scriptColumn" in recordPayload.data ? recordPayload.data.scriptColumn - 1 : 0;
                    sourceCodeLocation = scriptResource.createSourceCodeLocation(lineNumber, columnNumber);
                }
            }

            var profileData = recordPayload.data.profile;

            var record;
            switch (parentRecordPayload.type) {
            case InspectorBackend.Enum.Timeline.EventType.TimerFire:
                record = new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.TimerFired, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.timerId, profileData);
                break;
            case InspectorBackend.Enum.Timeline.EventType.EventDispatch:
                record = new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.EventDispatched, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.type, profileData, parentRecordPayload.data);
                break;
            case InspectorBackend.Enum.Timeline.EventType.ObserverCallback:
                record = new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.ObserverCallback, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.type, profileData);
                break;
            case InspectorBackend.Enum.Timeline.EventType.FireAnimationFrame:
                record = new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.AnimationFrameFired, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.id, profileData);
                break;
            case InspectorBackend.Enum.Timeline.EventType.FunctionCall:
                record = new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.ScriptEvaluated, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.id, profileData);
                break;
            case InspectorBackend.Enum.Timeline.EventType.RenderingFrame:
                record = new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.ScriptEvaluated, startTime, endTime, callFrames, sourceCodeLocation, parentRecordPayload.data.id, profileData);
                break;

            default:
                console.assert(false, "Missed FunctionCall embedded inside of: " + parentRecordPayload.type);
                break;
            }

            if (record) {
                this._webTimelineScriptRecordsExpectingScriptProfilerEvents.push(record);
                return record;
            }
            break;

        case InspectorBackend.Enum.Timeline.EventType.ProbeSample:
            // Pass the startTime as the endTime since this record type has no duration.
            sourceCodeLocation = WI.debuggerManager.probeForIdentifier(recordPayload.data.probeId).breakpoint.sourceCodeLocation;
            return new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.ProbeSampleRecorded, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.probeId);

        case InspectorBackend.Enum.Timeline.EventType.TimerInstall:
            console.assert(isNaN(endTime));

            // Pass the startTime as the endTime since this record type has no duration.
            var timerDetails = {timerId: recordPayload.data.timerId, timeout: recordPayload.data.timeout, repeating: !recordPayload.data.singleShot};
            return new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.TimerInstalled, startTime, startTime, callFrames, sourceCodeLocation, timerDetails);

        case InspectorBackend.Enum.Timeline.EventType.TimerRemove:
            console.assert(isNaN(endTime));

            // Pass the startTime as the endTime since this record type has no duration.
            return new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.TimerRemoved, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.timerId);

        case InspectorBackend.Enum.Timeline.EventType.RequestAnimationFrame:
            console.assert(isNaN(endTime));

            // Pass the startTime as the endTime since this record type has no duration.
            return new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.AnimationFrameRequested, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.id);

        case InspectorBackend.Enum.Timeline.EventType.CancelAnimationFrame:
            console.assert(isNaN(endTime));

            // Pass the startTime as the endTime since this record type has no duration.
            return new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.AnimationFrameCanceled, startTime, startTime, callFrames, sourceCodeLocation, recordPayload.data.id);

        default:
            console.error("Missing handling of Timeline Event Type: " + recordPayload.type);
        }

        return null;
    }

    _processEvent(recordPayload, parentRecordPayload)
    {
        console.assert(this.isCapturing());

        switch (recordPayload.type) {
        case InspectorBackend.Enum.Timeline.EventType.TimeStamp:
            var timestamp = this._activeRecording.computeElapsedTime(recordPayload.startTime);
            var eventMarker = new WI.TimelineMarker(timestamp, WI.TimelineMarker.Type.TimeStamp, recordPayload.data.message);
            this._activeRecording.addEventMarker(eventMarker);
            break;

        case InspectorBackend.Enum.Timeline.EventType.Time:
        case InspectorBackend.Enum.Timeline.EventType.TimeEnd:
            // FIXME: <https://webkit.org/b/150690> Web Inspector: Show console.time/timeEnd ranges in Timeline
            // FIXME: Make use of "message" payload properties.
            break;

        default:
            return this._processRecord(recordPayload, parentRecordPayload);
        }

        return null;
    }

    _loadNewRecording()
    {
        if (this._activeRecording && this._activeRecording.isEmpty())
            return;

        let instruments = this.enabledTimelineTypes.map((type) => WI.Instrument.createForTimelineType(type));
        let identifier = this._nextRecordingIdentifier++;
        let newRecording = new WI.TimelineRecording(identifier, WI.UIString("Timeline Recording %d").format(identifier), instruments);

        this._recordings.push(newRecording);
        this.dispatchEventToListeners(WI.TimelineManager.Event.RecordingCreated, {recording: newRecording});

        if (this._capturingState === TimelineManager.CapturingState.Starting || this._capturingState === TimelineManager.CapturingState.Active)
            this.stopCapturing();

        var oldRecording = this._activeRecording;
        if (oldRecording)
            oldRecording.unloaded();

        this._activeRecording = newRecording;

        // COMPATIBILITY (iOS 8): When using Legacy timestamps, a navigation will have computed
        // the main resource's will send request timestamp in terms of the last page's base timestamp.
        // Now that we have navigated, we should reset the legacy base timestamp and the
        // will send request timestamp for the new main resource. This way, all new timeline
        // records will be computed relative to the new navigation.
        if (this._mainResourceForAutoCapturing && WI.TimelineRecording.isLegacy) {
            console.assert(this._mainResourceForAutoCapturing.originalRequestWillBeSentTimestamp);
            this._activeRecording.setLegacyBaseTimestamp(this._mainResourceForAutoCapturing.originalRequestWillBeSentTimestamp);
            this._mainResourceForAutoCapturing._requestSentTimestamp = 0;
        }

        this.dispatchEventToListeners(WI.TimelineManager.Event.RecordingLoaded, {oldRecording});
    }

    _callFramesFromPayload(payload)
    {
        if (!payload)
            return null;

        return payload.map((x) => WI.CallFrame.fromPayload(WI.assumingMainTarget(), x));
    }

    _addRecord(record)
    {
        this._activeRecording.addRecord(record);

        // Only worry about dead time after the load event.
        if (WI.networkManager.mainFrame && isNaN(WI.networkManager.mainFrame.loadEventTimestamp))
            this._resetAutoRecordingDeadTimeTimeout();
    }

    _attemptAutoCapturingForFrame(frame)
    {
        if (!this._autoCaptureOnPageLoad)
            return false;

        if (!frame.isMainFrame())
            return false;

        if (!InspectorBackend.hasDomain("Timeline"))
            return false;

        // COMPATIBILITY (iOS 9): Timeline.setAutoCaptureEnabled did not exist.
        // Perform auto capture in the frontend.
        if (!InspectorBackend.hasCommand("Timeline.setAutoCaptureEnabled"))
            return this._legacyAttemptStartAutoCapturingForFrame(frame);

        if (!this._shouldSetAutoCapturingMainResource)
            return false;

        console.assert(this.isCapturing(), "We saw autoCaptureStarted so we should already be capturing");

        let mainResource = frame.provisionalMainResource || frame.mainResource;
        if (mainResource === this._mainResourceForAutoCapturing)
            return false;

        let oldMainResource = frame.mainResource || null;
        this._isCapturingPageReload = oldMainResource !== null && oldMainResource.url === mainResource.url;

        this._mainResourceForAutoCapturing = mainResource;

        this._addRecord(new WI.ResourceTimelineRecord(mainResource));

        this._resetAutoRecordingMaxTimeTimeout();

        this._shouldSetAutoCapturingMainResource = false;

        return true;
    }

    _legacyAttemptStartAutoCapturingForFrame(frame)
    {
        if (this.isCapturing() && !this._mainResourceForAutoCapturing)
            return false;

        let mainResource = frame.provisionalMainResource || frame.mainResource;
        if (mainResource === this._mainResourceForAutoCapturing)
            return false;

        let oldMainResource = frame.mainResource || null;
        this._isCapturingPageReload = oldMainResource !== null && oldMainResource.url === mainResource.url;

        if (this._capturingState === TimelineManager.CapturingState.Starting || this._capturingState === TimelineManager.CapturingState.Active)
            this.stopCapturing();

        this._mainResourceForAutoCapturing = mainResource;

        this._loadNewRecording();

        this.startCapturing();

        this._addRecord(new WI.ResourceTimelineRecord(mainResource));

        this._resetAutoRecordingMaxTimeTimeout();

        return true;
    }

    _stopAutoRecordingSoon()
    {
        if (!WI.settings.timelinesAutoStop.value)
            return;

        // Only auto stop when auto capturing.
        if (!this.isCapturing() || !this._mainResourceForAutoCapturing)
            return;

        if (this._stopCapturingTimeout)
            clearTimeout(this._stopCapturingTimeout);
        this._stopCapturingTimeout = setTimeout(this._boundStopCapturing, WI.TimelineManager.MaximumAutoRecordDurationAfterLoadEvent);
    }

    _resetAutoRecordingMaxTimeTimeout()
    {
        if (!WI.settings.timelinesAutoStop.value)
            return;

        if (this._stopCapturingTimeout)
            clearTimeout(this._stopCapturingTimeout);
        this._stopCapturingTimeout = setTimeout(this._boundStopCapturing, WI.TimelineManager.MaximumAutoRecordDuration);
    }

    _resetAutoRecordingDeadTimeTimeout()
    {
        if (!WI.settings.timelinesAutoStop.value)
            return;

        // Only monitor dead time when auto capturing.
        if (!this.isCapturing() || !this._mainResourceForAutoCapturing)
            return;

        // Avoid unnecessary churning of timeout identifier by not tickling until 10ms have passed.
        let now = Date.now();
        if (now <= this._lastDeadTimeTickle)
            return;
        this._lastDeadTimeTickle = now + 10;

        if (this._deadTimeTimeout)
            clearTimeout(this._deadTimeTimeout);
        this._deadTimeTimeout = setTimeout(this._boundStopCapturing, WI.TimelineManager.DeadTimeRequiredToStopAutoRecordingEarly);
    }

    _provisionalLoadStarted(event)
    {
        if (!this._enabled)
            return;

        this._attemptAutoCapturingForFrame(event.target);
    }

    _mainResourceDidChange(event)
    {
        if (!this._enabled)
            return;

        // Ignore resource events when there isn't a main frame yet. Those events are triggered by
        // loading the cached resources when the inspector opens, and they do not have timing information.
        if (!WI.networkManager.mainFrame)
            return;

        let frame = event.target;

        // When performing a page transition start a recording once the main resource changes.
        // We start a legacy capture because the backend wasn't available to automatically
        // initiate the capture, so the frontend must start the capture.
        if (this._transitioningPageTarget) {
            this._transitioningPageTarget = false;
            if (this._autoCaptureOnPageLoad)
                this._legacyAttemptStartAutoCapturingForFrame(frame);
            return;
        }

        if (this._attemptAutoCapturingForFrame(frame))
            return;

        if (!this.isCapturing())
            return;

        let mainResource = frame.mainResource;
        if (mainResource === this._mainResourceForAutoCapturing)
            return;

        this._addRecord(new WI.ResourceTimelineRecord(mainResource));
    }

    _resourceWasAdded(event)
    {
        if (!this._enabled)
            return;

        // Ignore resource events when there isn't a main frame yet. Those events are triggered by
        // loading the cached resources when the inspector opens, and they do not have timing information.
        if (!WI.networkManager.mainFrame)
            return;

        this._addRecord(new WI.ResourceTimelineRecord(event.data.resource));
    }

    _garbageCollected(event)
    {
        if (!this._enabled)
            return;

        let {collection} = event.data;
        this._addRecord(new WI.ScriptTimelineRecord(WI.ScriptTimelineRecord.EventType.GarbageCollected, collection.startTime, collection.endTime, null, null, collection));
    }

    _memoryPressure(event)
    {
        if (!this._enabled)
            return;

        this._activeRecording.addMemoryPressureEvent(event.data.memoryPressureEvent);
    }

    _handleTimelinesAutoStopSettingChanged(event)
    {
        if (WI.settings.timelinesAutoStop.value) {
            if (this._mainResourceForAutoCapturing && !isNaN(this._mainResourceForAutoCapturing.parentFrame.loadEventTimestamp))
                this._stopAutoRecordingSoon();
            else
                this._resetAutoRecordingMaxTimeTimeout();
            this._resetAutoRecordingDeadTimeTimeout();
        } else
            this.relaxAutoStop();
    }

    _scriptProfilerTypeToScriptTimelineRecordType(type)
    {
        switch (type) {
        case InspectorBackend.Enum.ScriptProfiler.EventType.API:
            return WI.ScriptTimelineRecord.EventType.APIScriptEvaluated;
        case InspectorBackend.Enum.ScriptProfiler.EventType.Microtask:
            return WI.ScriptTimelineRecord.EventType.MicrotaskDispatched;
        case InspectorBackend.Enum.ScriptProfiler.EventType.Other:
            return WI.ScriptTimelineRecord.EventType.ScriptEvaluated;
        }
    }

    _mergeScriptProfileRecords()
    {
        let nextRecord = function(list) { return list.shift() || null; };
        let nextWebTimelineRecord = nextRecord.bind(null, this._webTimelineScriptRecordsExpectingScriptProfilerEvents);
        let nextScriptProfilerRecord = nextRecord.bind(null, this._scriptProfilerRecords);
        let recordEnclosesRecord = function(record1, record2) {
            return record1.startTime <= record2.startTime && record1.endTime >= record2.endTime;
        };

        let webRecord = nextWebTimelineRecord();
        let profilerRecord = nextScriptProfilerRecord();

        while (webRecord && profilerRecord) {
            // Skip web records with parent web records. For example an EvaluateScript with an EvaluateScript parent.
            if (webRecord.parent instanceof WI.ScriptTimelineRecord) {
                console.assert(recordEnclosesRecord(webRecord.parent, webRecord), "Timeline Record incorrectly wrapping another Timeline Record");
                webRecord = nextWebTimelineRecord();
                continue;
            }

            // Normal case of a Web record wrapping a Script record.
            if (recordEnclosesRecord(webRecord, profilerRecord)) {
                webRecord.profilePayload = profilerRecord.profilePayload;
                profilerRecord = nextScriptProfilerRecord();

                // If there are more script profile records in the same time interval, add them
                // as individual script evaluated records with profiles. This can happen with
                // web microtask checkpoints that are technically inside of other web records.
                // FIXME: <https://webkit.org/b/152903> Web Inspector: Timeline Cleanup: Better Timeline Record for Microtask Checkpoints
                while (profilerRecord && recordEnclosesRecord(webRecord, profilerRecord)) {
                    this._addRecord(profilerRecord);
                    profilerRecord = nextScriptProfilerRecord();
                }

                webRecord = nextWebTimelineRecord();
                continue;
            }

            // Profiler Record is entirely after the Web Record. This would mean an empty web record.
            if (profilerRecord.startTime > webRecord.endTime) {
                console.warn("Unexpected case of a Timeline record not containing a ScriptProfiler event and profile data");
                webRecord = nextWebTimelineRecord();
                continue;
            }

            // Non-wrapped profiler record.
            console.warn("Unexpected case of a ScriptProfiler event not being contained by a Timeline record");
            this._addRecord(profilerRecord);
            profilerRecord = nextScriptProfilerRecord();
        }

        // Skipping the remaining ScriptProfiler events to match the current UI for handling Timeline records.
        // However, the remaining ScriptProfiler records are valid and could be shown.
        // FIXME: <https://webkit.org/b/152904> Web Inspector: Timeline UI should keep up with processing all incoming records
    }

    _updateAutoCaptureInstruments(targets)
    {
        console.assert(this._enabled);

        let enabledTimelineTypes = this.enabledTimelineTypes;

        for (let target of targets) {
            if (!target.hasCommand("Timeline.setInstruments"))
                continue;

            let instrumentSet = new Set;
            for (let timelineType of enabledTimelineTypes) {
                switch (timelineType) {
                case WI.TimelineRecord.Type.Script:
                    instrumentSet.add(InspectorBackend.Enum.Timeline.Instrument.ScriptProfiler);
                    break;
                case WI.TimelineRecord.Type.HeapAllocations:
                    instrumentSet.add(InspectorBackend.Enum.Timeline.Instrument.Heap);
                    break;
                case WI.TimelineRecord.Type.Network:
                case WI.TimelineRecord.Type.RenderingFrame:
                case WI.TimelineRecord.Type.Layout:
                    instrumentSet.add(InspectorBackend.Enum.Timeline.Instrument.Timeline);
                    break;
                case WI.TimelineRecord.Type.CPU:
                    instrumentSet.add(InspectorBackend.Enum.Timeline.Instrument.CPU);
                    break;
                case WI.TimelineRecord.Type.Memory:
                    instrumentSet.add(InspectorBackend.Enum.Timeline.Instrument.Memory);
                    break;
                case WI.TimelineRecord.Type.Media:
                    // COMPATIBILITY (iOS 13): Animation domain did not exist yet.
                    if (InspectorBackend.hasDomain("Animation"))
                        instrumentSet.add(InspectorBackend.Enum.Timeline.Instrument.Animation);
                    break;
                }
            }

            target.TimelineAgent.setInstruments(Array.from(instrumentSet));
        }
    }

    _handleDOMNodeDidFireEvent(event)
    {
        if (!this._enabled)
            return;

        let domNode = event.target;
        if (!domNode.isMediaElement())
            return;

        let {domEvent} = event.data;

        let mediaTimeline = this._activeRecording.timelineForRecordType(WI.TimelineRecord.Type.Media);
        console.assert(mediaTimeline);

        let record = mediaTimeline.recordForMediaElementEvents(domNode);
        if (!record) {
            record = new WI.MediaTimelineRecord(WI.MediaTimelineRecord.EventType.MediaElement, domNode);
            this._addRecord(record);
        }

        record.addDOMEvent(domEvent.timestamp, domEvent);
    }

    _handleDOMNodePowerEfficientPlaybackStateChanged(event)
    {
        if (!this._enabled)
            return;

        let domNode = event.target;
        console.assert(domNode.isMediaElement());

        let {timestamp, isPowerEfficient} = event.data;

        let mediaTimeline = this._activeRecording.timelineForRecordType(WI.TimelineRecord.Type.Media);
        console.assert(mediaTimeline);

        let record = mediaTimeline.recordForMediaElementEvents(domNode);
        if (!record) {
            record = new WI.MediaTimelineRecord(WI.MediaTimelineRecord.EventType.MediaElement, domNode);
            this._addRecord(record);
        }

        record.powerEfficientPlaybackStateChanged(timestamp, isPowerEfficient);
    }
};

WI.TimelineManager.CapturingState = {
    Inactive: "inactive",
    Starting: "starting",
    Active: "active",
    Stopping: "stopping",
};

WI.TimelineManager.Event = {
    CapturingStateChanged: "timeline-manager-capturing-started",
    RecordingCreated: "timeline-manager-recording-created",
    RecordingLoaded: "timeline-manager-recording-loaded",
    RecordingImported: "timeline-manager-recording-imported",
};

WI.TimelineManager.MaximumAutoRecordDuration = 90_000; // 90 seconds
WI.TimelineManager.MaximumAutoRecordDurationAfterLoadEvent = 10_000; // 10 seconds
WI.TimelineManager.DeadTimeRequiredToStopAutoRecordingEarly = 2_000; // 2 seconds
