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

WI.MemoryTimelineView = class MemoryTimelineView extends WI.TimelineView
{
    constructor(timeline, extraArguments)
    {
        super(timeline, extraArguments);

        this._recording = extraArguments.recording;

        console.assert(timeline.type === WI.TimelineRecord.Type.Memory, timeline);

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

        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;
            chartSubtitleElement.title = tooltip;

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

        let usageTooltip = WI.UIString("Breakdown of each memory category at the end of the selected time range");
        let usageChartContainerElement = createChartContainer(overviewElement, WI.UIString("Breakdown"), usageTooltip);
        this._usageCircleChart = new WI.CircleChart({size: 120, innerRadiusRatio: 0.5});
        usageChartContainerElement.appendChild(this._usageCircleChart.element);
        this._usageLegendElement = usageChartContainerElement.appendChild(document.createElement("div"));
        this._usageLegendElement.classList.add("legend", "usage");

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

        let maxComparisonTooltip = WI.UIString("Comparison of total memory size at the end of the selected time range to the maximum memory size in this recording");
        let maxComparisonChartContainerElement = createChartContainer(overviewElement, WI.UIString("Max Comparison"), maxComparisonTooltip);
        this._maxComparisonCircleChart = new WI.CircleChart({size: 120, innerRadiusRatio: 0.5});
        maxComparisonChartContainerElement.appendChild(this._maxComparisonCircleChart.element);
        this._maxComparisonLegendElement = maxComparisonChartContainerElement.appendChild(document.createElement("div"));
        this._maxComparisonLegendElement.classList.add("legend", "maximum");

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

        this._timelineRuler = new WI.TimelineRuler;
        this.addSubview(this._timelineRuler);
        detailsContainerElement.appendChild(this._timelineRuler.element);

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

        this._didInitializeCategories = false;
        this._categoryViews = [];
        this._usageLegendSizeElementMap = new Map;

        this._maxSize = 0;
        this._maxComparisonMaximumSizeElement = null;
        this._maxComparisonCurrentSizeElement = null;

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

    // Static

    static displayNameForCategory(category)
    {
        switch (category) {
        case WI.MemoryCategory.Type.JavaScript:
            return WI.UIString("JavaScript");
        case WI.MemoryCategory.Type.Images:
            return WI.UIString("Images");
        case WI.MemoryCategory.Type.Layers:
            return WI.UIString("Layers");
        case WI.MemoryCategory.Type.Page:
            return WI.UIString("Page");
        }
    }

    // Public

    shown()
    {
        super.shown();

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

    hidden()
    {
        super.hidden();
    }

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

    reset()
    {
        super.reset();

        this._maxSize = 0;

        this._cachedLegendRecord = null;
        this._cachedLegendMaxSize = undefined;
        this._cachedLegendCurrentSize = undefined;

        this._usageCircleChart.clear();
        this._usageCircleChart.needsLayout();
        this._clearUsageLegend();

        this._maxComparisonCircleChart.clear();
        this._maxComparisonCircleChart.needsLayout();
        this._clearMaxComparisonLegend();

        for (let categoryView of this._categoryViews)
            categoryView.clear();
    }

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

    // Protected

    get showsFilterBar() { return false; }

    layout()
    {
        // Always update timeline ruler.
        this._timelineRuler.zeroTime = this.zeroTime;
        this._timelineRuler.startTime = this.startTime;
        this._timelineRuler.endTime = this.endTime;

        if (!this._didInitializeCategories)
            return;

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

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

        // Don't include the record before the graph start if the graph start is within a gap.
        let includeRecordBeforeStart = !discontinuities.length || discontinuities[0].startTime > graphStartTime;

        // FIXME: <https://webkit.org/b/153759> Web Inspector: Memory Timelines should better extend to future data
        let visibleRecords = this.representedObject.recordsInTimeRange(graphStartTime, visibleEndTime, includeRecordBeforeStart);
        if (!visibleRecords.length)
            return;

        // Update total usage chart with the last record's data.
        let lastRecord = visibleRecords.lastValue;
        let values = [];
        for (let {size} of lastRecord.categories)
            values.push(size);
        this._usageCircleChart.values = values;
        this._usageCircleChart.updateLayout();
        this._updateUsageLegend(lastRecord);

        // Update maximum comparison chart.
        this._maxComparisonCircleChart.values = [lastRecord.totalSize, this._maxSize - lastRecord.totalSize];
        this._maxComparisonCircleChart.updateLayout();
        this._updateMaxComparisonLegend(lastRecord.totalSize);

        // FIXME: <https://webkit.org/b/153758> Web Inspector: Memory Timeline View should be responsive / resizable
        const categoryViewWidth = 800;
        const categoryViewHeight = 75;

        let secondsPerPixel = (graphEndTime - graphStartTime) / categoryViewWidth;

        let categoryDataMap = {};
        for (let categoryView of this._categoryViews)
            categoryDataMap[categoryView.category] = {dataPoints: [], max: -Infinity, min: Infinity};

        for (let record of visibleRecords) {
            let time = record.startTime;
            let discontinuity = null;
            if (discontinuities.length && discontinuities[0].endTime < time)
                discontinuity = discontinuities.shift();

            for (let category of record.categories) {
                let categoryData = categoryDataMap[category.type];

                if (discontinuity) {
                    if (categoryData.dataPoints.length) {
                        let previousDataPoint = categoryData.dataPoints.lastValue;
                        categoryData.dataPoints.push({time: discontinuity.startTime, size: previousDataPoint.size});
                    }

                    categoryData.dataPoints.push({time: discontinuity.startTime, size: 0});
                    categoryData.dataPoints.push({time: discontinuity.endTime, size: 0});
                    categoryData.dataPoints.push({time: discontinuity.endTime, size: category.size});
                }

                categoryData.dataPoints.push({time, size: category.size});
                categoryData.max = Math.max(categoryData.max, category.size);
                categoryData.min = Math.min(categoryData.min, category.size);
            }
        }

        // 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 layoutCategoryView(categoryView, categoryData) {
            let {dataPoints, min, max} = categoryData;

            if (min === Infinity)
                min = 0;
            if (max === -Infinity)
                max = 0;

            // Zoom in to the top of each graph to accentuate small changes.
            let graphMin = min * 0.95;
            let graphMax = (max * 1.05) - graphMin;

            function xScale(time) {
                return (time - graphStartTime) / secondsPerPixel;
            }
            function yScale(size) {
                return categoryViewHeight - (((size - graphMin) / graphMax) * categoryViewHeight);
            }

            categoryView.layoutWithDataPoints(dataPoints, visibleEndTime, min, max, xScale, yScale);
        }

        for (let categoryView of this._categoryViews)
            layoutCategoryView(categoryView, categoryDataMap[categoryView.category]);
    }

    // Private

    _clearUsageLegend()
    {
        for (let sizeElement of this._usageLegendSizeElementMap.values())
            sizeElement.textContent = emDash;

        let totalElement = this._usageCircleChart.centerElement.firstChild;
        if (totalElement) {
            totalElement.firstChild.textContent = "";
            totalElement.lastChild.textContent = "";
        }
    }

    _updateUsageLegend(record)
    {
        if (this._cachedLegendRecord === record)
            return;

        this._cachedLegendRecord = record;

        for (let {type, size} of record.categories) {
            let sizeElement = this._usageLegendSizeElementMap.get(type);
            sizeElement.textContent = Number.isFinite(size) ? Number.bytesToString(size) : emDash;
        }

        let centerElement = this._usageCircleChart.centerElement;
        let totalElement = centerElement.firstChild;
        if (!totalElement) {
            totalElement = centerElement.appendChild(document.createElement("div"));
            totalElement.classList.add("total-usage");
            totalElement.appendChild(document.createElement("span")); // firstChild
            totalElement.appendChild(document.createElement("br"));
            totalElement.appendChild(document.createElement("span")); // lastChild
        }

        let totalSize = Number.bytesToString(record.totalSize).split(/\s+/);
        totalElement.firstChild.textContent = totalSize[0];
        totalElement.lastChild.textContent = totalSize[1];
    }

    _clearMaxComparisonLegend()
    {
        this._maxComparisonMaximumSizeElement.textContent = emDash;
        this._maxComparisonCurrentSizeElement.textContent = emDash;

        let totalElement = this._maxComparisonCircleChart.centerElement.firstChild;
        if (totalElement)
            totalElement.textContent = "";
    }

    _updateMaxComparisonLegend(currentSize)
    {
        if (this._cachedLegendMaxSize === this._maxSize && this._cachedLegendCurrentSize === currentSize)
            return;

        this._cachedLegendMaxSize = this._maxSize;
        this._cachedLegendCurrentSize = currentSize;

        this._maxComparisonMaximumSizeElement.textContent = Number.isFinite(this._maxSize) ? Number.bytesToString(this._maxSize) : emDash;
        this._maxComparisonCurrentSizeElement.textContent = Number.isFinite(currentSize) ? Number.bytesToString(currentSize) : emDash;

        let centerElement = this._maxComparisonCircleChart.centerElement;
        let totalElement = centerElement.firstChild;
        if (!totalElement) {
            totalElement = centerElement.appendChild(document.createElement("div"));
            totalElement.classList.add("max-percentage");
        }

        // The chart will only show a perfect circle if the current and max are really the same value.
        // So do a little massaging to ensure 0.9995 doesn't get rounded up to 1.
        let percent = currentSize / this._maxSize;
        totalElement.textContent = Number.percentageString(percent === 1 ? percent : (percent - 0.0005));
    }

    _initializeCategoryViews(record)
    {
        console.assert(!this._didInitializeCategories, "Should only initialize category views once");
        this._didInitializeCategories = true;

        let segments = [];
        let lastCategoryViewElement = null;

        function appendLegendRow(legendElement, swatchClass, label, tooltip) {
            let rowElement = legendElement.appendChild(document.createElement("div"));
            rowElement.classList.add("row");
            let swatchElement = rowElement.appendChild(document.createElement("div"));
            swatchElement.classList.add("swatch", swatchClass);
            let labelElement = rowElement.appendChild(document.createElement("p"));
            labelElement.classList.add("label");
            labelElement.textContent = label;
            let sizeElement = rowElement.appendChild(document.createElement("p"));
            sizeElement.classList.add("size");

            if (tooltip)
                rowElement.title = tooltip;

            return sizeElement;
        }

        for (let {type} of record.categories) {
            segments.push(type);

            // Per-category graph.
            let categoryView = new WI.MemoryCategoryView(type, WI.MemoryTimelineView.displayNameForCategory(type));
            this._categoryViews.push(categoryView);
            if (!lastCategoryViewElement)
                this._detailsContainerElement.appendChild(categoryView.element);
            else
                this._detailsContainerElement.insertBefore(categoryView.element, lastCategoryViewElement);
            lastCategoryViewElement = categoryView.element;

            // Usage legend rows.
            let sizeElement = appendLegendRow.call(this, this._usageLegendElement, type, WI.MemoryTimelineView.displayNameForCategory(type));
            this._usageLegendSizeElementMap.set(type, sizeElement);
        }

        this._usageCircleChart.segments = segments;

        // Max comparison legend rows.
        this._maxComparisonCircleChart.segments = ["current", "remainder"];
        this._maxComparisonMaximumSizeElement = appendLegendRow.call(this, this._maxComparisonLegendElement, "remainder", WI.UIString("Maximum"), WI.UIString("Maximum maximum memory size in this recording"));
        this._maxComparisonCurrentSizeElement = appendLegendRow.call(this, this._maxComparisonLegendElement, "current", WI.UIString("Current"), WI.UIString("Total memory size at the end of the selected time range"));
    }

    _memoryTimelineRecordAdded(event)
    {
        let memoryTimelineRecord = event.data.record;
        console.assert(memoryTimelineRecord instanceof WI.MemoryTimelineRecord);

        if (!this._didInitializeCategories)
            this._initializeCategoryViews(memoryTimelineRecord);

        this._maxSize = Math.max(this._maxSize, memoryTimelineRecord.totalSize);

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