/*
* 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.HeapSnapshotDataGridTree = class HeapSnapshotDataGridTree extends WI.Object
{
    constructor(heapSnapshot, sortComparator)
    {
        super();

        console.assert(heapSnapshot instanceof WI.HeapSnapshotProxy || heapSnapshot instanceof WI.HeapSnapshotDiffProxy);

        this._heapSnapshot = heapSnapshot;
        this._heapSnapshot.addEventListener(WI.HeapSnapshotProxy.Event.CollectedNodes, this._heapSnapshotCollectedNodes, this);

        this._children = [];
        this._sortComparator = sortComparator;

        this._visible = false;
        this._popover = null;
        this._popoverGridNode = null;
        this._popoverTargetElement = null;

        this.populateTopLevel();
    }

    // Static

    static buildSortComparator(columnIdentifier, sortOrder)
    {
        let multiplier = sortOrder === WI.DataGrid.SortOrder.Ascending ? 1 : -1;
        let numberCompare = (columnIdentifier, a, b) => multiplier * (a.data[columnIdentifier] - b.data[columnIdentifier]);
        let nameCompare = (a, b) => {
            // Sort by property name if available. Property names before no property name.
            if (a.propertyName || b.propertyName) {
                if (a.propertyName && !b.propertyName)
                    return multiplier * -1;
                if (!a.propertyName && b.propertyName)
                    return multiplier * 1;
                let propertyNameCompare = a.propertyName.extendedLocaleCompare(b.propertyName);
                console.assert(propertyNameCompare !== 0, "Property names should be unique, we shouldn't have equal property names.");
                return multiplier * propertyNameCompare;
            }

            // Sort by class name and object id if no property name.
            let classNameCompare = a.data.className.extendedLocaleCompare(b.data.className);
            if (classNameCompare)
                return multiplier * classNameCompare;
            if (a.data.id || b.data.id)
                return multiplier * (a.data.id - b.data.id);
            return 0;
        };

        switch (columnIdentifier) {
        case "retainedSize":
            return numberCompare.bind(this, "retainedSize");
        case "size":
            return numberCompare.bind(this, "size");
        case "count":
            return numberCompare.bind(this, "count");
        case "className":
            return nameCompare;
        }
    }

    // Public

    get heapSnapshot() { return this._heapSnapshot; }

    get visible() { return this._visible; }
    get popoverGridNode() { return this._popoverGridNode; }
    set popoverGridNode(x) { this._popoverGridNode = x; }
    get popoverTargetElement() { return this._popoverTargetElement; }
    set popoverTargetElement(x) { this._popoverTargetElement = x; }

    get popover()
    {
        if (!this._popover) {
            this._popover = new WI.Popover(this);
            this._popover.windowResizeHandler = () => {
                let bounds = WI.Rect.rectFromClientRect(this._popoverTargetElement.getBoundingClientRect());
                this._popover.present(bounds.pad(2), [WI.RectEdge.MAX_Y, WI.RectEdge.MIN_Y, WI.RectEdge.MAX_X]);
            };
        }

        return this._popover;
    }

    get children()
    {
        return this._children;
    }

    appendChild(node)
    {
        this._children.push(node);
    }

    insertChild(node, index)
    {
        this._children.splice(index, 0, node);
    }

    removeChild(node)
    {
        this._children.remove(node, true);
    }

    removeChildren()
    {
        this._children = [];
    }

    set sortComparator(comparator)
    {
        this._sortComparator = comparator;
        this.sort();
    }

    sort()
    {
        let children = this._children;
        children.sort(this._sortComparator);

        for (let i = 0; i < children.length; ++i) {
            children[i]._recalculateSiblings(i);
            children[i].sort();
        }
    }

    shown()
    {
        this._visible = true;
    }

    hidden()
    {
        this._visible = false;

        if (this._popover && this._popover.visible)
            this._popover.dismiss();
    }

    // Popover delegate

    willDismissPopover(popover)
    {
        this._popoverGridNode = null;
        this._popoverTargetElement = null;
    }

    // Protected

    get alwaysShowRetainedSize()
    {
        return false;
    }

    populateTopLevel()
    {
        // Implemented by subclasses.
    }

    removeCollectedNodes(collectedNodes)
    {
        // Implemented by subclasses.
    }

    didPopulate()
    {
        this.sort();

        this.dispatchEventToListeners(WI.HeapSnapshotDataGridTree.Event.DidPopulate);
    }

    // Private

    _heapSnapshotCollectedNodes(event)
    {
        this.removeCollectedNodes(event.data.collectedNodes);
    }
};

WI.HeapSnapshotDataGridTree.Event = {
    DidPopulate: "heap-snapshot-data-grid-tree-did-populate",
};

WI.HeapSnapshotInstancesDataGridTree = class HeapSnapshotInstancesDataGridTree extends WI.HeapSnapshotDataGridTree
{
    get alwaysShowRetainedSize()
    {
        return false;
    }

    populateTopLevel()
    {
        // Populate the first level with the different classes.
        let skipInternalOnlyObjects = !WI.isEngineeringBuild || !WI.settings.engineeringShowInternalObjectsInHeapSnapshot.value;

        for (let [className, {size, retainedSize, count, internalCount, deadCount, objectCount}] of this.heapSnapshot.categories) {
            console.assert(count > 0);

            // Possibly skip internal only classes.
            if (skipInternalOnlyObjects && count === internalCount)
                continue;

            // FIXME: <https://webkit.org/b/157905> Web Inspector: Provide a way to toggle between showing only live objects and live+dead objects
            let liveCount = count - deadCount;
            if (!liveCount)
                continue;

            // If over half of the objects with this class name are Object sub-types, treat this as an Object category.
            // This can happen if the page has a JavaScript Class with the same name as a native class.
            let isObjectSubcategory = (objectCount / count) > 0.5;

            this.appendChild(new WI.HeapSnapshotClassDataGridNode({className, size, retainedSize, isObjectSubcategory, count: liveCount}, this));
        }

        this.didPopulate();
    }

    removeCollectedNodes(collectedNodes)
    {
        for (let classDataGridNode of this.children) {
            let {count, deadCount} = this.heapSnapshot.categories.get(classDataGridNode.data.className);
            let liveCount = count - deadCount;
            classDataGridNode.updateCount(liveCount);
            if (liveCount)
                classDataGridNode.removeCollectedNodes(collectedNodes);
        }

        this.didPopulate();
    }
};

WI.HeapSnapshotObjectGraphDataGridTree = class HeapSnapshotInstancesDataGridTree extends WI.HeapSnapshotDataGridTree
{
    get alwaysShowRetainedSize()
    {
        return true;
    }

    populateTopLevel()
    {
        this.heapSnapshot.instancesWithClassName("GlobalObject", (instances) => {
            for (let instance of instances)
                this.appendChild(new WI.HeapSnapshotInstanceDataGridNode(instance, this));
        });

        this.heapSnapshot.instancesWithClassName("Window", (instances) => {
            for (let instance of instances) {
                // FIXME: Why is the window.Window Function classified as a Window?
                // In any case, ignore objects not dominated by the root, as they
                // are probably not what we want.
                if (instance.dominatorNodeIdentifier === 0)
                    this.appendChild(new WI.HeapSnapshotInstanceDataGridNode(instance, this));
            }

            this.didPopulate();
        });
    }
};
