/*
 * Copyright (C) 2013 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.TimelineRecording = class TimelineRecording extends WI.Object
{
    constructor(identifier, displayName, instruments)
    {
        super();

        this._identifier = identifier;
        this._timelines = new Map;
        this._displayName = displayName;
        this._capturing = false;
        this._readonly = false;
        this._imported = false;
        this._instruments = instruments || [];

        this._startTime = NaN;
        this._endTime = NaN;

        this._discontinuityStartTime = NaN;
        this._discontinuities = null;
        this._firstRecordOfTypeAfterDiscontinuity = new Set;

        this._exportDataRecords = null;
        this._exportDataMarkers = null;
        this._exportDataMemoryPressureEvents = null;
        this._exportDataSampleStackTraces = null;
        this._exportDataSampleDurations = null;

        this._topDownCallingContextTree = new WI.CallingContextTree(WI.CallingContextTree.Type.TopDown);
        this._bottomUpCallingContextTree = new WI.CallingContextTree(WI.CallingContextTree.Type.BottomUp);
        this._topFunctionsTopDownCallingContextTree = new WI.CallingContextTree(WI.CallingContextTree.Type.TopFunctionsTopDown);
        this._topFunctionsBottomUpCallingContextTree = new WI.CallingContextTree(WI.CallingContextTree.Type.TopFunctionsBottomUp);

        for (let type of WI.TimelineManager.availableTimelineTypes()) {
            let timeline = WI.Timeline.create(type);
            this._timelines.set(type, timeline);
            timeline.addEventListener(WI.Timeline.Event.TimesUpdated, this._timelineTimesUpdated, this);
        }

        // For legacy backends, we compute the elapsed time of records relative to this timestamp.
        this._legacyFirstRecordedTimestamp = NaN;

        this.reset(true);
    }

    // Static

    static sourceCodeTimelinesSupported()
    {
        // FIXME: Support Network Timeline in ServiceWorker.
        return WI.sharedApp.debuggableType === WI.DebuggableType.Web;
    }

    // Import / Export

    static import(identifier, json, displayName)
    {
        let {startTime, endTime, discontinuities, instrumentTypes, records, markers, memoryPressureEvents, sampleStackTraces, sampleDurations} = json;
        let importedDisplayName = WI.UIString("Imported - %s").format(displayName);
        let instruments = instrumentTypes.map((type) => WI.Instrument.createForTimelineType(type));
        let recording = new WI.TimelineRecording(identifier, importedDisplayName, instruments);

        recording._readonly = true;
        recording._imported = true;
        recording._startTime = startTime;
        recording._endTime = endTime;
        recording._discontinuities = discontinuities;

        recording.initializeCallingContextTrees(sampleStackTraces, sampleDurations);

        for (let recordJSON of records) {
            let record = WI.TimelineRecord.fromJSON(recordJSON);
            if (record) {
                recording.addRecord(record);

                if (record instanceof WI.ScriptTimelineRecord)
                    record.profilePayload = recording._topDownCallingContextTree.toCPUProfilePayload(record.startTime, record.endTime);
            }
        }

        for (let memoryPressureJSON of memoryPressureEvents) {
            let memoryPressureEvent = WI.MemoryPressureEvent.fromJSON(memoryPressureJSON);
            if (memoryPressureEvent)
                recording.addMemoryPressureEvent(memoryPressureEvent);
        }

        // Add markers once we've transitioned the active recording.
        setTimeout(() => {
            recording.__importing = true;

            for (let markerJSON of markers) {
                let marker = WI.TimelineMarker.fromJSON(markerJSON);
                if (marker)
                    recording.addEventMarker(marker);
            }

            recording.__importing = false;
        });

        return recording;
    }

    exportData()
    {
        console.assert(this.canExport(), "Attempted to export a recording which should not be exportable.");

        // FIXME: Overview data (sourceCodeTimelinesMap).
        // FIXME: Record hierarchy (parent / child relationship) is lost.

        return {
            displayName: this._displayName,
            startTime: this._startTime,
            endTime: this._endTime,
            discontinuities: this._discontinuities,
            instrumentTypes: this._instruments.map((instrument) => instrument.timelineRecordType),
            records: this._exportDataRecords,
            markers: this._exportDataMarkers,
            memoryPressureEvents: this._exportDataMemoryPressureEvents,
            sampleStackTraces: this._exportDataSampleStackTraces,
            sampleDurations: this._exportDataSampleDurations,
        };
    }

    // Public

    get displayName() { return this._displayName; }
    get identifier() { return this._identifier; }
    get timelines() { return this._timelines; }
    get instruments() { return this._instruments; }
    get capturing() { return this._capturing; }
    get readonly() { return this._readonly; }
    get imported() { return this._imported; }
    get startTime() { return this._startTime; }
    get endTime() { return this._endTime; }

    get topDownCallingContextTree() { return this._topDownCallingContextTree; }
    get bottomUpCallingContextTree() { return this._bottomUpCallingContextTree; }
    get topFunctionsTopDownCallingContextTree() { return this._topFunctionsTopDownCallingContextTree; }
    get topFunctionsBottomUpCallingContextTree() { return this._topFunctionsBottomUpCallingContextTree; }

    start(initiatedByBackend)
    {
        console.assert(!this._capturing, "Attempted to start an already started session.");
        console.assert(!this._readonly, "Attempted to start a readonly session.");

        this._capturing = true;

        for (let instrument of this._instruments)
            instrument.startInstrumentation(initiatedByBackend);

        if (!isNaN(this._discontinuityStartTime)) {
            for (let instrument of this._instruments)
                this._firstRecordOfTypeAfterDiscontinuity.add(instrument.timelineRecordType);
        }
    }

    stop(initiatedByBackend)
    {
        console.assert(this._capturing, "Attempted to stop an already stopped session.");
        console.assert(!this._readonly, "Attempted to stop a readonly session.");

        this._capturing = false;

        for (let instrument of this._instruments)
            instrument.stopInstrumentation(initiatedByBackend);
    }

    capturingStarted(startTime)
    {
        // A discontinuity occurs when the recording is stopped and resumed at
        // a future time. Capturing started signals the end of the current
        // discontinuity, if one exists.
        if (!isNaN(this._discontinuityStartTime)) {
            this._discontinuities.push({
                startTime: this._discontinuityStartTime,
                endTime: startTime,
            });
            this._discontinuityStartTime = NaN;
        }
    }

    capturingStopped(endTime)
    {
        this._discontinuityStartTime = endTime;
    }

    saveIdentityToCookie()
    {
        // Do nothing. Timeline recordings are not persisted when the inspector is
        // re-opened, so do not attempt to restore by identifier or display name.
    }

    isEmpty()
    {
        for (var timeline of this._timelines.values()) {
            if (timeline.records.length)
                return false;
        }

        return true;
    }

    unloaded(importing)
    {
        console.assert(importing || !this.isEmpty(), "Shouldn't unload an empty recording; it should be reused instead.");

        this._readonly = true;

        this.dispatchEventToListeners(WI.TimelineRecording.Event.Unloaded);
    }

    reset(suppressEvents)
    {
        console.assert(!this._readonly, "Can't reset a read-only recording.");

        this._sourceCodeTimelinesMap = new Map;

        this._startTime = NaN;
        this._endTime = NaN;

        this._discontinuityStartTime = NaN;
        this._discontinuities = [];
        this._firstRecordOfTypeAfterDiscontinuity.clear();

        this._exportDataRecords = [];
        this._exportDataMarkers = [];
        this._exportDataMemoryPressureEvents = [];
        this._exportDataSampleStackTraces = [];
        this._exportDataSampleDurations = [];

        this._topDownCallingContextTree.reset();
        this._bottomUpCallingContextTree.reset();
        this._topFunctionsTopDownCallingContextTree.reset();
        this._topFunctionsBottomUpCallingContextTree.reset();

        for (var timeline of this._timelines.values())
            timeline.reset(suppressEvents);

        WI.RenderingFrameTimelineRecord.resetFrameIndex();

        if (!suppressEvents) {
            this.dispatchEventToListeners(WI.TimelineRecording.Event.Reset);
            this.dispatchEventToListeners(WI.TimelineRecording.Event.TimesUpdated);
        }
    }

    get sourceCodeTimelines()
    {
        let timelines = [];
        for (let timelinesForSourceCode of this._sourceCodeTimelinesMap.values())
            timelines.pushAll(timelinesForSourceCode.values());
        return timelines;
    }

    timelineForInstrument(instrument)
    {
        return this._timelines.get(instrument.timelineRecordType);
    }

    instrumentForTimeline(timeline)
    {
        return this._instruments.find((instrument) => instrument.timelineRecordType === timeline.type);
    }

    timelineForRecordType(recordType)
    {
        return this._timelines.get(recordType);
    }

    addInstrument(instrument)
    {
        console.assert(instrument instanceof WI.Instrument, instrument);
        console.assert(!this._instruments.includes(instrument), this._instruments, instrument);

        this._instruments.push(instrument);

        this.dispatchEventToListeners(WI.TimelineRecording.Event.InstrumentAdded, {instrument});
    }

    removeInstrument(instrument)
    {
        console.assert(instrument instanceof WI.Instrument, instrument);
        console.assert(this._instruments.includes(instrument), this._instruments, instrument);

        this._instruments.remove(instrument);

        this.dispatchEventToListeners(WI.TimelineRecording.Event.InstrumentRemoved, {instrument});
    }

    addEventMarker(marker)
    {
        this._exportDataMarkers.push(marker);

        if (!this._capturing && !this.__importing)
            return;

        this.dispatchEventToListeners(WI.TimelineRecording.Event.MarkerAdded, {marker});
    }

    addRecord(record)
    {
        this._exportDataRecords.push(record);

        let timeline = this._timelines.get(record.type);
        console.assert(timeline, record, this._timelines);
        if (!timeline)
            return;

        let discontinuity = null;
        if (this._firstRecordOfTypeAfterDiscontinuity.take(record.type))
            discontinuity = this._discontinuities.lastValue;

        // Add the record to the global timeline by type.
        timeline.addRecord(record, {discontinuity});

        // Some records don't have source code timelines.
        if (record.type === WI.TimelineRecord.Type.Network
            || record.type === WI.TimelineRecord.Type.RenderingFrame
            || record.type === WI.TimelineRecord.Type.CPU
            || record.type === WI.TimelineRecord.Type.Memory
            || record.type === WI.TimelineRecord.Type.HeapAllocations)
            return;

        if (!WI.TimelineRecording.sourceCodeTimelinesSupported())
            return;

        // Add the record to the source code timelines.
        let sourceCode = null;
        if (record.sourceCodeLocation)
            sourceCode = record.sourceCodeLocation.sourceCode;
        else if (record.type === WI.TimelineRecord.Type.Media) {
            if (record.domNode && record.domNode.frame)
                sourceCode = record.domNode.frame.mainResource;
        }
        if (!sourceCode)
            sourceCode = WI.networkManager.mainFrame.provisionalMainResource || WI.networkManager.mainFrame.mainResource;

        var sourceCodeTimelines = this._sourceCodeTimelinesMap.get(sourceCode);
        if (!sourceCodeTimelines) {
            sourceCodeTimelines = new Map;
            this._sourceCodeTimelinesMap.set(sourceCode, sourceCodeTimelines);
        }

        var newTimeline = false;
        var key = this._keyForRecord(record);
        var sourceCodeTimeline = sourceCodeTimelines.get(key);
        if (!sourceCodeTimeline) {
            sourceCodeTimeline = new WI.SourceCodeTimeline(sourceCode, record.sourceCodeLocation, record.type, record.eventType);
            sourceCodeTimelines.set(key, sourceCodeTimeline);
            newTimeline = true;
        }

        sourceCodeTimeline.addRecord(record);

        if (newTimeline)
            this.dispatchEventToListeners(WI.TimelineRecording.Event.SourceCodeTimelineAdded, {sourceCodeTimeline});
    }

    addMemoryPressureEvent(memoryPressureEvent)
    {
        this._exportDataMemoryPressureEvents.push(memoryPressureEvent);

        let memoryTimeline = this._timelines.get(WI.TimelineRecord.Type.Memory);
        console.assert(memoryTimeline, this._timelines);
        if (!memoryTimeline)
            return;

        memoryTimeline.addMemoryPressureEvent(memoryPressureEvent);
    }

    discontinuitiesInTimeRange(startTime, endTime)
    {
        return this._discontinuities.filter((item) => item.startTime <= endTime && item.endTime >= startTime);
    }

    addScriptInstrumentForProgrammaticCapture()
    {
        for (let instrument of this._instruments) {
            if (instrument instanceof WI.ScriptInstrument)
                return;
        }

        this.addInstrument(new WI.ScriptInstrument);

        let instrumentTypes = this._instruments.map((instrument) => instrument.timelineRecordType);
        WI.timelineManager.enabledTimelineTypes = instrumentTypes;
    }

    computeElapsedTime(timestamp)
    {
        if (!timestamp || isNaN(timestamp))
            return NaN;

        // COMPATIBILITY (iOS 8): old backends send timestamps (seconds or milliseconds since the epoch),
        // rather than seconds elapsed since timeline capturing started. We approximate the latter by
        // subtracting the start timestamp, as old versions did not use monotonic times.
        if (WI.TimelineRecording.isLegacy === undefined)
            WI.TimelineRecording.isLegacy = timestamp > WI.TimelineRecording.TimestampThresholdForLegacyRecordConversion;

        if (!WI.TimelineRecording.isLegacy)
            return timestamp;

        // If the record's start time is large, but not really large, then it is seconds since epoch
        // not millseconds since epoch, so convert it to milliseconds.
        if (timestamp < WI.TimelineRecording.TimestampThresholdForLegacyAssumedMilliseconds)
            timestamp *= 1000;

        if (isNaN(this._legacyFirstRecordedTimestamp))
            this._legacyFirstRecordedTimestamp = timestamp;

        // Return seconds since the first recorded value.
        return (timestamp - this._legacyFirstRecordedTimestamp) / 1000.0;
    }

    setLegacyBaseTimestamp(timestamp)
    {
        console.assert(isNaN(this._legacyFirstRecordedTimestamp));

        if (timestamp < WI.TimelineRecording.TimestampThresholdForLegacyAssumedMilliseconds)
            timestamp *= 1000;

        this._legacyFirstRecordedTimestamp = timestamp;
    }

    initializeTimeBoundsIfNecessary(timestamp)
    {
        if (isNaN(this._startTime)) {
            console.assert(isNaN(this._endTime));

            this._startTime = timestamp;
            this._endTime = timestamp;

            this.dispatchEventToListeners(WI.TimelineRecording.Event.TimesUpdated);
        }
    }

    initializeCallingContextTrees(stackTraces, sampleDurations)
    {
        this._exportDataSampleStackTraces.pushAll(stackTraces);
        this._exportDataSampleDurations.pushAll(sampleDurations);

        for (let i = 0; i < stackTraces.length; i++) {
            this._topDownCallingContextTree.updateTreeWithStackTrace(stackTraces[i], sampleDurations[i]);
            this._bottomUpCallingContextTree.updateTreeWithStackTrace(stackTraces[i], sampleDurations[i]);
            this._topFunctionsTopDownCallingContextTree.updateTreeWithStackTrace(stackTraces[i], sampleDurations[i]);
            this._topFunctionsBottomUpCallingContextTree.updateTreeWithStackTrace(stackTraces[i], sampleDurations[i]);
        }
    }

    canExport()
    {
        if (this._capturing)
            return false;

        if (isNaN(this._startTime))
            return false;

        return true;
    }

    // Private

    _keyForRecord(record)
    {
        var key = record.type;
        if (record instanceof WI.ScriptTimelineRecord || record instanceof WI.LayoutTimelineRecord)
            key += ":" + record.eventType;
        if (record instanceof WI.ScriptTimelineRecord && record.eventType === WI.ScriptTimelineRecord.EventType.EventDispatched)
            key += ":" + record.details;
        if (record instanceof WI.MediaTimelineRecord) {
            key += ":" + record.eventType;
            if (record.eventType === WI.MediaTimelineRecord.EventType.DOMEvent) {
                if (record.domEvent && record.domEvent.eventName)
                    key += ":" + record.domEvent.eventName;
            } else if (record.eventType === WI.MediaTimelineRecord.EventType.PowerEfficientPlaybackStateChanged)
                key += ":" + (record.isPowerEfficient ? "enabled" : "disabled");
        }
        if (record.sourceCodeLocation)
            key += ":" + record.sourceCodeLocation.lineNumber + ":" + record.sourceCodeLocation.columnNumber;
        return key;
    }

    _timelineTimesUpdated(event)
    {
        var timeline = event.target;
        var changed = false;

        if (isNaN(this._startTime) || timeline.startTime < this._startTime) {
            this._startTime = timeline.startTime;
            changed = true;
        }

        if (isNaN(this._endTime) || this._endTime < timeline.endTime) {
            this._endTime = timeline.endTime;
            changed = true;
        }

        if (changed)
            this.dispatchEventToListeners(WI.TimelineRecording.Event.TimesUpdated);
    }
};

WI.TimelineRecording.Event = {
    Reset: "timeline-recording-reset",
    Unloaded: "timeline-recording-unloaded",
    SourceCodeTimelineAdded: "timeline-recording-source-code-timeline-added",
    InstrumentAdded: "timeline-recording-instrument-added",
    InstrumentRemoved: "timeline-recording-instrument-removed",
    TimesUpdated: "timeline-recording-times-updated",
    MarkerAdded: "timeline-recording-marker-added",
};

WI.TimelineRecording.isLegacy = undefined;
WI.TimelineRecording.TimestampThresholdForLegacyRecordConversion = 10000000; // Some value not near zero.
WI.TimelineRecording.TimestampThresholdForLegacyAssumedMilliseconds = 1420099200000; // Date.parse("Jan 1, 2015"). Milliseconds since epoch.

WI.TimelineRecording.SerializationVersion = 1;
