/*
 * Copyright (C) 2010 Google 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:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
 * OWNER OR 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.
 */

WebInspector.HeapSnapshotView = function(parent, profile)
{
    WebInspector.View.call(this);

    this.element.addStyleClass("heap-snapshot-view");

    this.parent = parent;
    this.parent.addEventListener("profile added", this._updateBaseOptions, this);

    this.showCountAsPercent = false;
    this.showSizeAsPercent = false;
    this.showCountDeltaAsPercent = false;
    this.showSizeDeltaAsPercent = false;

    this.categories = {
        code: new WebInspector.ResourceCategory("code", WebInspector.UIString("Code"), "rgb(255,121,0)"),
        data: new WebInspector.ResourceCategory("data", WebInspector.UIString("Objects"), "rgb(47,102,236)")
    };

    var summaryContainer = document.createElement("div");
    summaryContainer.id = "heap-snapshot-summary-container";

    this.countsSummaryBar = new WebInspector.SummaryBar(this.categories);
    this.countsSummaryBar.element.className = "heap-snapshot-summary";
    this.countsSummaryBar.calculator = new WebInspector.HeapSummaryCountCalculator();
    var countsLabel = document.createElement("div");
    countsLabel.className = "heap-snapshot-summary-label";
    countsLabel.textContent = WebInspector.UIString("Count");
    this.countsSummaryBar.element.appendChild(countsLabel);
    summaryContainer.appendChild(this.countsSummaryBar.element);

    this.sizesSummaryBar = new WebInspector.SummaryBar(this.categories);
    this.sizesSummaryBar.element.className = "heap-snapshot-summary";
    this.sizesSummaryBar.calculator = new WebInspector.HeapSummarySizeCalculator();
    var sizesLabel = document.createElement("label");
    sizesLabel.className = "heap-snapshot-summary-label";
    sizesLabel.textContent = WebInspector.UIString("Size");
    this.sizesSummaryBar.element.appendChild(sizesLabel);
    summaryContainer.appendChild(this.sizesSummaryBar.element);

    this.element.appendChild(summaryContainer);

    var columns = {
        cons: { title: WebInspector.UIString("Constructor"), disclosure: true, sortable: true },
        count: { title: WebInspector.UIString("Count"), width: "54px", sortable: true },
        size: { title: WebInspector.UIString("Size"), width: "72px", sort: "descending", sortable: true },
        // \xb1 is a "plus-minus" sign.
        countDelta: { title: WebInspector.UIString("\xb1 Count"), width: "72px", sortable: true },
        sizeDelta: { title: WebInspector.UIString("\xb1 Size"), width: "72px", sortable: true }
    };

    this.dataGrid = new WebInspector.DataGrid(columns);
    this.dataGrid.addEventListener("sorting changed", this._sortData, this);
    this.dataGrid.element.addEventListener("mousedown", this._mouseDownInDataGrid.bind(this), true);
    this.element.appendChild(this.dataGrid.element);

    this.profile = profile;

    this.baseSelectElement = document.createElement("select");
    this.baseSelectElement.className = "status-bar-item";
    this.baseSelectElement.addEventListener("change", this._changeBase.bind(this), false);
    this._updateBaseOptions();

    this.percentButton = new WebInspector.StatusBarButton("", "percent-time-status-bar-item status-bar-item");
    this.percentButton.addEventListener("click", this._percentClicked.bind(this), false);

    this._loadProfile(this.profile, profileCallback.bind(this));

    function profileCallback(profile)
    {
        var list = this._getProfiles();
        var profileIndex;
        for (var i = 0; i < list.length; ++i)
            if (list[i].uid === profile.uid) {
                profileIndex = i;
                break;
            }
        if (profileIndex > 0)
            this.baseSelectElement.selectedIndex = profileIndex - 1;
        else
            this.baseSelectElement.selectedIndex = profileIndex;
        this._resetDataGridList(resetCompleted.bind(this));
    }

    function resetCompleted()
    {
        this.refresh();
        this._updatePercentButton();
    }
}

WebInspector.HeapSnapshotView.prototype = {
    get statusBarItems()
    {
        return [this.baseSelectElement, this.percentButton.element];
    },

    get profile()
    {
        return this._profile;
    },

    set profile(profile)
    {
        this._profile = profile;
    },

    show: function(parentElement)
    {
        WebInspector.View.prototype.show.call(this, parentElement);
        this.dataGrid.updateWidths();
    },

    hide: function()
    {
        WebInspector.View.prototype.hide.call(this);
        this._currentSearchResultIndex = -1;
    },

    resize: function()
    {
        if (this.dataGrid)
            this.dataGrid.updateWidths();
    },

    refresh: function()
    {
        this.dataGrid.removeChildren();

        var children = this.snapshotDataGridList.children;
        var count = children.length;
        for (var index = 0; index < count; ++index)
            this.dataGrid.appendChild(children[index]);

        this._updateSummaryGraph();
    },

    refreshShowAsPercents: function()
    {
        this._updatePercentButton();
        this.refreshVisibleData();
    },

    _deleteSearchMatchedFlags: function(node)
    {
        delete node._searchMatchedConsColumn;
        delete node._searchMatchedCountColumn;
        delete node._searchMatchedSizeColumn;
        delete node._searchMatchedCountDeltaColumn;
        delete node._searchMatchedSizeDeltaColumn;
    },

    searchCanceled: function()
    {
        if (this._searchResults) {
            for (var i = 0; i < this._searchResults.length; ++i) {
                var profileNode = this._searchResults[i].profileNode;
                this._deleteSearchMatchedFlags(profileNode);
                profileNode.refresh();
            }
        }

        delete this._searchFinishedCallback;
        this._currentSearchResultIndex = -1;
        this._searchResults = [];
    },

    performSearch: function(query, finishedCallback)
    {
        // Call searchCanceled since it will reset everything we need before doing a new search.
        this.searchCanceled();

        query = query.trim();

        if (!query.length)
            return;

        this._searchFinishedCallback = finishedCallback;

        var helper = WebInspector.HeapSnapshotView.SearchHelper;

        var operationAndNumber = helper.parseOperationAndNumber(query);
        var operation = operationAndNumber[0];
        var queryNumber = operationAndNumber[1];

        var percentUnits = helper.percents.test(query);
        var megaBytesUnits = helper.megaBytes.test(query);
        var kiloBytesUnits = helper.kiloBytes.test(query);
        var bytesUnits = helper.bytes.test(query);

        var queryNumberBytes = (megaBytesUnits ? (queryNumber * 1024 * 1024) : (kiloBytesUnits ? (queryNumber * 1024) : queryNumber));

        function matchesQuery(heapSnapshotDataGridNode)
        {
            WebInspector.HeapSnapshotView.prototype._deleteSearchMatchedFlags(heapSnapshotDataGridNode);

            if (percentUnits) {
                heapSnapshotDataGridNode._searchMatchedCountColumn = operation(heapSnapshotDataGridNode.countPercent, queryNumber);
                heapSnapshotDataGridNode._searchMatchedSizeColumn = operation(heapSnapshotDataGridNode.sizePercent, queryNumber);
                heapSnapshotDataGridNode._searchMatchedCountDeltaColumn = operation(heapSnapshotDataGridNode.countDeltaPercent, queryNumber);
                heapSnapshotDataGridNode._searchMatchedSizeDeltaColumn = operation(heapSnapshotDataGridNode.sizeDeltaPercent, queryNumber);
            } else if (megaBytesUnits || kiloBytesUnits || bytesUnits) {
                heapSnapshotDataGridNode._searchMatchedSizeColumn = operation(heapSnapshotDataGridNode.size, queryNumberBytes);
                heapSnapshotDataGridNode._searchMatchedSizeDeltaColumn = operation(heapSnapshotDataGridNode.sizeDelta, queryNumberBytes);
            } else {
                heapSnapshotDataGridNode._searchMatchedCountColumn = operation(heapSnapshotDataGridNode.count, queryNumber);
                heapSnapshotDataGridNode._searchMatchedCountDeltaColumn = operation(heapSnapshotDataGridNode.countDelta, queryNumber);
            }

            if (heapSnapshotDataGridNode.constructorName.hasSubstring(query, true))
                heapSnapshotDataGridNode._searchMatchedConsColumn = true;

            if (heapSnapshotDataGridNode._searchMatchedConsColumn ||
                heapSnapshotDataGridNode._searchMatchedCountColumn ||
                heapSnapshotDataGridNode._searchMatchedSizeColumn ||
                heapSnapshotDataGridNode._searchMatchedCountDeltaColumn ||
                heapSnapshotDataGridNode._searchMatchedSizeDeltaColumn) {
                heapSnapshotDataGridNode.refresh();
                return true;
            }

            return false;
        }

        var current = this.snapshotDataGridList.children[0];
        var depth = 0;
        var info = {};

        // The second and subsequent levels of heap snapshot nodes represent retainers,
        // so recursive expansion will be infinite, since a graph is being traversed.
        // So default to a recursion cap of 2 levels.
        const maxDepth = 2;

        while (current) {
            if (matchesQuery(current))
                this._searchResults.push({ profileNode: current });
            current = current.traverseNextNode(false, null, (depth >= maxDepth), info);
            depth += info.depthChange;
        }

        finishedCallback(this, this._searchResults.length);
    },

    // FIXME: move these methods to a superclass, inherit both views from it.
    jumpToFirstSearchResult: WebInspector.CPUProfileView.prototype.jumpToFirstSearchResult,
    jumpToLastSearchResult: WebInspector.CPUProfileView.prototype.jumpToLastSearchResult,
    jumpToNextSearchResult: WebInspector.CPUProfileView.prototype.jumpToNextSearchResult,
    jumpToPreviousSearchResult: WebInspector.CPUProfileView.prototype.jumpToPreviousSearchResult,
    showingFirstSearchResult: WebInspector.CPUProfileView.prototype.showingFirstSearchResult,
    showingLastSearchResult: WebInspector.CPUProfileView.prototype.showingLastSearchResult,
    _jumpToSearchResult: WebInspector.CPUProfileView.prototype._jumpToSearchResult,

    refreshVisibleData: function()
    {
        var child = this.dataGrid.children[0];
        while (child) {
            child.refresh();
            child = child.traverseNextNode(false, null, true);
        }
        this._updateSummaryGraph();
    },

    _changeBase: function()
    {
        if (this.baseSnapshot.uid === this._getProfiles()[this.baseSelectElement.selectedIndex].uid)
            return;

        this._resetDataGridList(resetCompleted.bind(this));

        function resetCompleted() {
            this.refresh();

            if (!this.currentQuery || !this._searchFinishedCallback || !this._searchResults)
                return;

            // The current search needs to be performed again. First negate out previous match
            // count by calling the search finished callback with a negative number of matches.
            // Then perform the search again with the same query and callback.
            this._searchFinishedCallback(this, -this._searchResults.length);
            this.performSearch(this.currentQuery, this._searchFinishedCallback);
        }
    },

    _createSnapshotDataGridList: function()
    {
        if (this._snapshotDataGridList)
          delete this._snapshotDataGridList;

        this._snapshotDataGridList = new WebInspector.HeapSnapshotDataGridList(this, this.baseSnapshot.entries, this.profile.entries);
        return this._snapshotDataGridList;
    },

    _getProfiles: function()
    {
        return WebInspector.panels.profiles.getProfiles(WebInspector.HeapSnapshotProfileType.TypeId);
    },

    _loadProfile: function(profile, callback)
    {
        if (profile._loaded) {
            callback(profile);
            return;
        }

        InspectorBackend.getProfile(profile.typeId, profile.uid, loadedCallback.bind(this));

        function loadedCallback(loadedSnapshot) {
            profile.children = loadedSnapshot.head.children;
            profile.entries = loadedSnapshot.head.entries;
            profile.lowlevels = loadedSnapshot.head.lowlevels;
            this._prepareProfile(profile);
            profile._loaded = true;
            this.parent.updateProfile(profile);
            callback(profile);
        }
    },

    _mouseDownInDataGrid: function(event)
    {
        if (event.detail < 2)
            return;

        var cell = event.target.enclosingNodeOrSelfWithNodeName("td");
        if (!cell || (!cell.hasStyleClass("count-column") && !cell.hasStyleClass("size-column") && !cell.hasStyleClass("countDelta-column") && !cell.hasStyleClass("sizeDelta-column")))
            return;

        if (cell.hasStyleClass("count-column"))
            this.showCountAsPercent = !this.showCountAsPercent;
        else if (cell.hasStyleClass("size-column"))
            this.showSizeAsPercent = !this.showSizeAsPercent;
        else if (cell.hasStyleClass("countDelta-column"))
            this.showCountDeltaAsPercent = !this.showCountDeltaAsPercent;
        else if (cell.hasStyleClass("sizeDelta-column"))
            this.showSizeDeltaAsPercent = !this.showSizeDeltaAsPercent;

        this.refreshShowAsPercents();

        event.preventDefault();
        event.stopPropagation();
    },

    get _isShowingAsPercent()
    {
        return this.showCountAsPercent && this.showSizeAsPercent && this.showCountDeltaAsPercent && this.showSizeDeltaAsPercent;
    },

    _percentClicked: function(event)
    {
        var currentState = this._isShowingAsPercent;
        this.showCountAsPercent = !currentState;
        this.showSizeAsPercent = !currentState;
        this.showCountDeltaAsPercent = !currentState;
        this.showSizeDeltaAsPercent = !currentState;
        this.refreshShowAsPercents();
    },

    _prepareProfile: function(profile)
    {
        for (var profileEntry in profile.entries)
            profile.entries[profileEntry].retainers = {};
        profile.clusters = {};

        for (var addr in profile.children) {
            var retainer = profile.children[addr];
            var retainerId = retainer.constructorName + ':' + addr;
            for (var childAddr in retainer) {
                if (childAddr === 'constructorName') continue;
                var item = retainer[childAddr];
                var itemId = item.constructorName + ':' + childAddr;
                if ((item.constructorName === 'Object' || item.constructorName === 'Array')) {
                    if (!(itemId in profile.clusters))
                        profile.clusters[itemId] = { constructorName: itemId, retainers: {} };
                    mergeRetainers(profile.clusters[itemId], item);
                }
                mergeRetainers(profile.entries[item.constructorName], item);
            }
        }

        function mergeRetainers(entry, item)
        {
            if (!(retainer.constructorName in entry.retainers))
               entry.retainers[retainer.constructorName] = { constructorName: retainer.constructorName, count: 0, clusters: {} };
            var retainerEntry = entry.retainers[retainer.constructorName];
            retainerEntry.count += item.count;
            if (retainer.constructorName === 'Object' || retainer.constructorName === 'Array')
                retainerEntry.clusters[retainerId] = true;
        }
    },

    _resetDataGridList: function(callback)
    {
        this._loadProfile(this._getProfiles()[this.baseSelectElement.selectedIndex], profileLoaded.bind(this));

        function profileLoaded(profile)
        {
            this.baseSnapshot = profile;
            var lastComparator = WebInspector.HeapSnapshotDataGridList.propertyComparator("size", false);
            if (this.snapshotDataGridList)
                lastComparator = this.snapshotDataGridList.lastComparator;
            this.snapshotDataGridList = this._createSnapshotDataGridList();
            this.snapshotDataGridList.sort(lastComparator, true);
            callback();
        }
    },

    _sortData: function()
    {
        var sortAscending = this.dataGrid.sortOrder === "ascending";
        var sortColumnIdentifier = this.dataGrid.sortColumnIdentifier;
        var sortProperty = {
            cons: ["cons", null],
            count: ["count", null],
            size: ["size", "count"],
            countDelta: this.showCountDeltaAsPercent ? ["countDeltaPercent", null] : ["countDelta", null],
            sizeDelta: this.showSizeDeltaAsPercent ? ["sizeDeltaPercent", "countDeltaPercent"] : ["sizeDelta", "sizeDeltaPercent"]
        }[sortColumnIdentifier];

        this.snapshotDataGridList.sort(WebInspector.HeapSnapshotDataGridList.propertyComparator(sortProperty[0], sortProperty[1], sortAscending));

        this.refresh();
    },

    _updateBaseOptions: function()
    {
        var list = this._getProfiles();
        // We're assuming that snapshots can only be added.
        if (this.baseSelectElement.length === list.length)
            return;

        for (var i = this.baseSelectElement.length, n = list.length; i < n; ++i) {
            var baseOption = document.createElement("option");
            var title = list[i].title;
            if (!title.indexOf(UserInitiatedProfileName))
                title = WebInspector.UIString("Snapshot %d", title.substring(UserInitiatedProfileName.length + 1));
            baseOption.label = WebInspector.UIString("Compared to %s", title);
            this.baseSelectElement.appendChild(baseOption);
        }
    },

    _updatePercentButton: function()
    {
        if (this._isShowingAsPercent) {
            this.percentButton.title = WebInspector.UIString("Show absolute counts and sizes.");
            this.percentButton.toggled = true;
        } else {
            this.percentButton.title = WebInspector.UIString("Show counts and sizes as percentages.");
            this.percentButton.toggled = false;
        }
    },

    _updateSummaryGraph: function()
    {
        this.countsSummaryBar.calculator.showAsPercent = this._isShowingAsPercent;
        this.countsSummaryBar.update(this.profile.lowlevels);

        this.sizesSummaryBar.calculator.showAsPercent = this._isShowingAsPercent;
        this.sizesSummaryBar.update(this.profile.lowlevels);
    }
};

WebInspector.HeapSnapshotView.prototype.__proto__ = WebInspector.View.prototype;

WebInspector.HeapSnapshotView.SearchHelper = {
    // In comparators, we assume that a value from a node is passed as the first parameter.
    operations: {
        LESS: function (a, b) { return a !== null && a < b; },
        LESS_OR_EQUAL: function (a, b) { return a !== null && a <= b; },
        EQUAL: function (a, b) { return a !== null && a === b; },
        GREATER_OR_EQUAL: function (a, b) { return a !== null && a >= b; },
        GREATER: function (a, b) { return a !== null && a > b; }
    },

    operationParsers: {
        LESS: /^<(\d+)/,
        LESS_OR_EQUAL: /^<=(\d+)/,
        GREATER_OR_EQUAL: /^>=(\d+)/,
        GREATER: /^>(\d+)/
    },

    parseOperationAndNumber: function(query)
    {
        var operations = WebInspector.HeapSnapshotView.SearchHelper.operations;
        var parsers = WebInspector.HeapSnapshotView.SearchHelper.operationParsers;
        for (var operation in parsers) {
            var match = query.match(parsers[operation]);
            if (match !== null)
                return [operations[operation], parseFloat(match[1])];
        }
        return [operations.EQUAL, parseFloat(query)];
    },

    percents: /%$/,

    megaBytes: /MB$/i,

    kiloBytes: /KB$/i,

    bytes: /B$/i
}

WebInspector.HeapSummaryCalculator = function(lowLevelField)
{
    this.total = 1;
    this.lowLevelField = lowLevelField;
}

WebInspector.HeapSummaryCalculator.prototype = {
    computeSummaryValues: function(lowLevels)
    {
        var highLevels = { data: 0, code: 0 };
        this.total = 0;
        for (var item in lowLevels) {
            var highItem = this._highFromLow(item);
            if (highItem) {
                var value = lowLevels[item][this.lowLevelField];
                highLevels[highItem] += value;
                this.total += value;
            }
        }
        var result = { categoryValues: highLevels };
        if (!this.showAsPercent)
            result.total = this.total;
        return result;
    },

    formatValue: function(value)
    {
        if (this.showAsPercent)
            return WebInspector.UIString("%.2f%%", value / this.total * 100.0);
        else
            return this._valueToString(value);
    },

    get showAsPercent()
    {
        return this._showAsPercent;
    },

    set showAsPercent(x)
    {
        this._showAsPercent = x;
    }
}

WebInspector.HeapSummaryCountCalculator = function()
{
    WebInspector.HeapSummaryCalculator.call(this, "count");
}

WebInspector.HeapSummaryCountCalculator.prototype = {
    _highFromLow: function(type)
    {
        if (type === "CODE_TYPE" || type === "SHARED_FUNCTION_INFO_TYPE" || type === "SCRIPT_TYPE") return "code";
        if (type === "STRING_TYPE" || type === "HEAP_NUMBER_TYPE" || type.match(/^JS_/)) return "data";
        return null;
    },

    _valueToString: function(value)
    {
        return value.toString();
    }
}

WebInspector.HeapSummaryCountCalculator.prototype.__proto__ = WebInspector.HeapSummaryCalculator.prototype;

WebInspector.HeapSummarySizeCalculator = function()
{
    WebInspector.HeapSummaryCalculator.call(this, "size");
}

WebInspector.HeapSummarySizeCalculator.prototype = {
    _highFromLow: function(type)
    {
        if (type === "CODE_TYPE" || type === "SHARED_FUNCTION_INFO_TYPE" || type === "SCRIPT_TYPE")
            return "code";
        if (type === "STRING_TYPE" || type === "HEAP_NUMBER_TYPE" || type.match(/^JS_/) || type.match(/_ARRAY_TYPE$/))
            return "data";
        return null;
    },

    _valueToString: Number.bytesToString
}

WebInspector.HeapSummarySizeCalculator.prototype.__proto__ = WebInspector.HeapSummaryCalculator.prototype;

WebInspector.HeapSnapshotDataGridNodeWithRetainers = function(owningTree)
{
    this.tree = owningTree;

    WebInspector.DataGridNode.call(this, null, this._hasRetainers);

    this.addEventListener("populate", this._populate, this);
};

WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype = {
    isEmptySet: function(set)
    {
        for (var x in set)
            return false;
        return true;
    },

    get _hasRetainers()
    {
        return !this.isEmptySet(this.retainers);
    },

    get _parent()
    {
        // For top-level nodes, return owning tree as a parent, not data grid.
        return this.parent !== this.dataGrid ? this.parent : this.tree;
    },

    _populate: function(event)
    {
        function appendDiffEntry(baseItem, snapshotItem)
        {
            this.appendChild(new WebInspector.HeapSnapshotDataGridRetainerNode(this.snapshotView, baseItem, snapshotItem, this.tree));
        }

        this.produceDiff(this.baseRetainers, this.retainers, appendDiffEntry.bind(this));

        if (this._parent) {
            var currentComparator = this._parent.lastComparator;
            if (currentComparator)
                this.sort(currentComparator, true);
        }

        this.removeEventListener("populate", this._populate, this);
    },

    produceDiff: function(baseEntries, currentEntries, callback)
    {
        for (var item in currentEntries)
            callback(baseEntries[item], currentEntries[item]);

        for (item in baseEntries) {
            if (!(item in currentEntries))
                callback(baseEntries[item], null);
        }
    },

    sort: function(comparator, force) {
        if (!force && this.lastComparator === comparator)
            return;

        this.children.sort(comparator);
        var childCount = this.children.length;
        for (var childIndex = 0; childIndex < childCount; ++childIndex)
            this.children[childIndex]._recalculateSiblings(childIndex);
        for (var i = 0; i < this.children.length; ++i) {
            var child = this.children[i];
            if (!force && (!child.expanded || child.lastComparator === comparator))
                continue;
            child.sort(comparator, force);
        }
        this.lastComparator = comparator;
    },

    signForDelta: function(delta) {
        if (delta === 0)
            return "";
        if (delta > 0)
            return "+";
        else
            return "\u2212";  // Math minus sign, same width as plus.
    },

    showDeltaAsPercent: function(value)
    {
        if (value === Number.POSITIVE_INFINITY)
            return WebInspector.UIString("new");
        else if (value === Number.NEGATIVE_INFINITY)
            return WebInspector.UIString("deleted");
        if (value > 1000.0)
            return WebInspector.UIString("%s >1000%%", this.signForDelta(value));
        return WebInspector.UIString("%s%.2f%%", this.signForDelta(value), Math.abs(value));
    },

    getTotalCount: function()
    {
        if (!this._count) {
            this._count = 0;
            for (var i = 0, n = this.children.length; i < n; ++i)
                this._count += this.children[i].count;
        }
        return this._count;
    },

    getTotalSize: function()
    {
        if (!this._size) {
            this._size = 0;
            for (var i = 0, n = this.children.length; i < n; ++i)
                this._size += this.children[i].size;
        }
        return this._size;
    },

    get countPercent()
    {
        return this.count / this._parent.getTotalCount() * 100.0;
    },

    get sizePercent()
    {
        return this.size / this._parent.getTotalSize() * 100.0;
    },

    get countDeltaPercent()
    {
        if (this.baseCount > 0) {
            if (this.count > 0)
                return this.countDelta / this.baseCount * 100.0;
            else
                return Number.NEGATIVE_INFINITY;
        } else
            return Number.POSITIVE_INFINITY;
    },

    get sizeDeltaPercent()
    {
        if (this.baseSize > 0) {
            if (this.size > 0)
                return this.sizeDelta / this.baseSize * 100.0;
            else
                return Number.NEGATIVE_INFINITY;
        } else
            return Number.POSITIVE_INFINITY;
    },

    get data()
    {
        var data = {};

        data["cons"] = this.constructorName;

        if (this.snapshotView.showCountAsPercent)
            data["count"] = WebInspector.UIString("%.2f%%", this.countPercent);
        else
            data["count"] = this.count;

        if (this.size !== null) {
            if (this.snapshotView.showSizeAsPercent)
                data["size"] = WebInspector.UIString("%.2f%%", this.sizePercent);
            else
                data["size"] = Number.bytesToString(this.size);
        } else
            data["size"] = "";

        if (this.snapshotView.showCountDeltaAsPercent)
            data["countDelta"] = this.showDeltaAsPercent(this.countDeltaPercent);
        else
            data["countDelta"] = WebInspector.UIString("%s%d", this.signForDelta(this.countDelta), Math.abs(this.countDelta));

        if (this.sizeDelta !== null) {
            if (this.snapshotView.showSizeDeltaAsPercent)
                data["sizeDelta"] = this.showDeltaAsPercent(this.sizeDeltaPercent);
            else
                data["sizeDelta"] = WebInspector.UIString("%s%s", this.signForDelta(this.sizeDelta), Number.bytesToString(Math.abs(this.sizeDelta)));
        } else
            data["sizeDelta"] = "";

        return data;
    },

    createCell: function(columnIdentifier)
    {
        var cell = WebInspector.DataGridNode.prototype.createCell.call(this, columnIdentifier);

        if ((columnIdentifier === "cons" && this._searchMatchedConsColumn) ||
            (columnIdentifier === "count" && this._searchMatchedCountColumn) ||
            (columnIdentifier === "size" && this._searchMatchedSizeColumn) ||
            (columnIdentifier === "countDelta" && this._searchMatchedCountDeltaColumn) ||
            (columnIdentifier === "sizeDelta" && this._searchMatchedSizeDeltaColumn))
            cell.addStyleClass("highlight");

        return cell;
    }
};

WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.__proto__ = WebInspector.DataGridNode.prototype;

WebInspector.HeapSnapshotDataGridNode = function(snapshotView, baseEntry, snapshotEntry, owningTree)
{
    this.snapshotView = snapshotView;

    if (!snapshotEntry)
        snapshotEntry = { constructorName: baseEntry.constructorName, count: 0, size: 0, retainers: {} };
    this.constructorName = snapshotEntry.constructorName;
    this.count = snapshotEntry.count;
    this.size = snapshotEntry.size;
    this.retainers = snapshotEntry.retainers;

    if (!baseEntry)
        baseEntry = { count: 0, size: 0, retainers: {} };
    this.baseCount = baseEntry.count;
    this.countDelta = this.count - this.baseCount;
    this.baseSize = baseEntry.size;
    this.sizeDelta = this.size - this.baseSize;
    this.baseRetainers = baseEntry.retainers;

    WebInspector.HeapSnapshotDataGridNodeWithRetainers.call(this, owningTree);
};

WebInspector.HeapSnapshotDataGridNode.prototype.__proto__ = WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype;

WebInspector.HeapSnapshotDataGridList = function(snapshotView, baseEntries, snapshotEntries)
{
    this.tree = this;
    this.snapshotView = snapshotView;
    this.children = [];
    this.lastComparator = null;
    this.populateChildren(baseEntries, snapshotEntries);
};

WebInspector.HeapSnapshotDataGridList.prototype = {
    appendChild: function(child)
    {
        this.insertChild(child, this.children.length);
    },

    insertChild: function(child, index)
    {
        this.children.splice(index, 0, child);
    },

    removeChildren: function()
    {
        this.children = [];
    },

    populateChildren: function(baseEntries, snapshotEntries)
    {
        function appendListEntry(baseItem, snapshotItem)
        {
            this.appendChild(new WebInspector.HeapSnapshotDataGridNode(this.snapshotView, baseItem, snapshotItem, this));
        }
        this.produceDiff(baseEntries, snapshotEntries, appendListEntry.bind(this));
    },

    produceDiff: WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.produceDiff,
    sort: WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.sort,
    getTotalCount: WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.getTotalCount,
    getTotalSize: WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.getTotalSize
};

WebInspector.HeapSnapshotDataGridList.propertyComparators = [{}, {}];

WebInspector.HeapSnapshotDataGridList.propertyComparator = function(property, property2, isAscending)
{
    var propertyHash = property + "#" + property2;
    var comparator = this.propertyComparators[(isAscending ? 1 : 0)][propertyHash];
    if (!comparator) {
        comparator = function(lhs, rhs) {
            var l = lhs[property], r = rhs[property];
            if ((l === null || r === null) && property2 !== null)
                l = lhs[property2], r = rhs[property2];
            var result = l < r ? -1 : (l > r ? 1 : 0);
            return isAscending ? result : -result;
        };
        this.propertyComparators[(isAscending ? 1 : 0)][propertyHash] = comparator;
    }
    return comparator;
};

WebInspector.HeapSnapshotDataGridRetainerNode = function(snapshotView, baseEntry, snapshotEntry, owningTree)
{
    this.snapshotView = snapshotView;

    if (!snapshotEntry)
        snapshotEntry = { constructorName: baseEntry.constructorName, count: 0, clusters: {} };
    this.constructorName = snapshotEntry.constructorName;
    this.count = snapshotEntry.count;
    this.retainers = this._calculateRetainers(this.snapshotView.profile, snapshotEntry.clusters);

    if (!baseEntry)
        baseEntry = { count: 0, clusters: {} };
    this.baseCount = baseEntry.count;
    this.countDelta = this.count - this.baseCount;
    this.baseRetainers = this._calculateRetainers(this.snapshotView.baseSnapshot, baseEntry.clusters);

    this.size = null;
    this.sizeDelta = null;

    WebInspector.HeapSnapshotDataGridNodeWithRetainers.call(this, owningTree);
}

WebInspector.HeapSnapshotDataGridRetainerNode.prototype = {
    get sizePercent()
    {
        return null;
    },

    get sizeDeltaPercent()
    {
        return null;
    },

    _calculateRetainers: function(snapshot, clusters)
    {
        var retainers = {};
        if (this.isEmptySet(clusters)) {
            if (this.constructorName in snapshot.entries)
                return snapshot.entries[this.constructorName].retainers;
        } else {
            // In case when an entry is retained by clusters, we need to gather up the list
            // of retainers by merging retainers of every cluster.
            // E.g. having such a tree:
            //   A
            //     Object:1  10
            //       X       3
            //       Y       4
            //     Object:2  5
            //       X       6
            //
            // will result in a following retainers list: X 9, Y 4.
            for (var clusterName in clusters) {
                if (clusterName in snapshot.clusters) {
                    var clusterRetainers = snapshot.clusters[clusterName].retainers;
                    for (var clusterRetainer in clusterRetainers) {
                        var clusterRetainerEntry = clusterRetainers[clusterRetainer];
                        if (!(clusterRetainer in retainers))
                            retainers[clusterRetainer] = { constructorName: clusterRetainerEntry.constructorName, count: 0, clusters: {} };
                        retainers[clusterRetainer].count += clusterRetainerEntry.count;
                        for (var clusterRetainerCluster in clusterRetainerEntry.clusters)
                            retainers[clusterRetainer].clusters[clusterRetainerCluster] = true;
                    }
                }
            }
        }
        return retainers;
    }
};

WebInspector.HeapSnapshotDataGridRetainerNode.prototype.__proto__ = WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype;


WebInspector.HeapSnapshotProfileType = function()
{
    WebInspector.ProfileType.call(this, WebInspector.HeapSnapshotProfileType.TypeId, WebInspector.UIString("HEAP SNAPSHOTS"));
}

WebInspector.HeapSnapshotProfileType.TypeId = "HEAP";

WebInspector.HeapSnapshotProfileType.prototype = {
    get buttonTooltip()
    {
        return WebInspector.UIString("Take heap snapshot.");
    },

    get buttonStyle()
    {
        return "heap-snapshot-status-bar-item status-bar-item";
    },

    buttonClicked: function()
    {
        InspectorBackend.takeHeapSnapshot();
    },

    get welcomeMessage()
    {
        return WebInspector.UIString("Get a heap snapshot by pressing the %s button on the status bar.");
    },

    createSidebarTreeElementForProfile: function(profile)
    {
        return new WebInspector.ProfileSidebarTreeElement(profile, WebInspector.UIString("Snapshot %d"), "heap-snapshot-sidebar-tree-item");
    },

    createView: function(profile)
    {
        return new WebInspector.HeapSnapshotView(WebInspector.panels.profiles, profile);
    }
}

WebInspector.HeapSnapshotProfileType.prototype.__proto__ = WebInspector.ProfileType.prototype;
