/*
 * Copyright (C) 2015 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.ObjectTreeView = class ObjectTreeView extends WI.Object
{
    constructor(object, mode, propertyPath, forceExpanding)
    {
        super();

        console.assert(object instanceof WI.RemoteObject);
        console.assert(!propertyPath || propertyPath instanceof WI.PropertyPath);

        var providedPropertyPath = propertyPath instanceof WI.PropertyPath;

        this._object = object;
        this._mode = mode || WI.ObjectTreeView.defaultModeForObject(object);
        this._propertyPath = propertyPath || new WI.PropertyPath(this._object, "this");
        this._expanded = false;
        this._hasLosslessPreview = false;
        this._includeProtoProperty = true;

        // If ObjectTree is used outside of the console, we do not know when to release
        // WeakMap entries. Currently collapse would work. For the console, we can just
        // listen for console clear events. Currently all ObjectTrees are in the console.
        this._inConsole = true;

        this._fetchStart = 0;
        this._fetchEnd = ObjectTreeView.showMoreFetchCount;
        this._fetchEndIndex = 0;

        // Always force expanding for classes.
        if (this._object.isClass())
            forceExpanding = true;

        this._element = document.createElement("div");
        this._element.__objectTree = this;
        this._element.className = "object-tree";

        if (this._object.preview) {
            this._previewView = new WI.ObjectPreviewView(this._object, this._object.preview);
            this._previewView.setOriginatingObjectInfo(this._object, providedPropertyPath ? propertyPath : null);
            this._previewView.element.addEventListener("click", this._handlePreviewOrTitleElementClick.bind(this));
            this._element.appendChild(this._previewView.element);

            if (this._previewView.lossless && !this._propertyPath.parent && !forceExpanding) {
                this._hasLosslessPreview = true;
                this.element.classList.add("lossless-preview");
            }
        } else {
            this._titleElement = document.createElement("span");
            this._titleElement.className = "title";
            this._titleElement.appendChild(WI.FormattedValue.createElementForRemoteObject(this._object));
            this._titleElement.addEventListener("click", this._handlePreviewOrTitleElementClick.bind(this));
            this._element.appendChild(this._titleElement);
        }

        this._outline = new WI.TreeOutline;
        this._outline.compact = true;
        this._outline.customIndent = true;
        this._outline.element.classList.add("object");
        this._element.appendChild(this._outline.element);

        // FIXME: Support editable ObjectTrees.
    }

    // Static

    static defaultModeForObject(object)
    {
        if (object.subtype === "class")
            return WI.ObjectTreeView.Mode.ClassAPI;

        return WI.ObjectTreeView.Mode.Properties;
    }

    static createEmptyMessageElement(message)
    {
        var emptyMessageElement = document.createElement("div");
        emptyMessageElement.className = "empty-message";
        emptyMessageElement.textContent = message;
        return emptyMessageElement;
    }

    static get showMoreFetchCount() { return 100; }

    static addShowMoreIfNeeded({resolvedValue, representation, parentTreeElement, handleShowMoreClicked, handleShowAllClicked})
    {
        console.assert(resolvedValue instanceof WI.RemoteObject, resolvedValue);
        console.assert(resolvedValue.isArray() || resolvedValue.isCollectionType());
        console.assert(typeof resolvedValue.size === "number" && resolvedValue.size > 0, resolvedValue);
        console.assert("_fetchStart" in representation, representation);
        console.assert("_fetchEnd" in representation, representation);
        console.assert("_fetchEndIndex" in representation, representation);
        console.assert(typeof handleShowMoreClicked === "function", handleShowMoreClicked);
        console.assert(typeof handleShowAllClicked === "function", handleShowAllClicked);

        // COMPATIBILITY (iOS 13): Runtime.getProperties/Runtime.getDisplayableProperties didn't support `fetchStart`/`fetchCount` yet.
        if (!InspectorBackend.hasCommand("Runtime.getProperties", "fetchStart"))
            return;

        let remaining = resolvedValue.size - representation._fetchEnd;
        if (remaining <= 0)
            return;

        let treeElement = new WI.TreeElement(document.createElement("span"));
        treeElement.selectable = false;
        parentTreeElement.insertChild(treeElement, representation._fetchEndIndex);

        // FIXME: <https://webkit.org/b/201965> Web Inspector: allow examining items in the middle of an array/collection without having to show all items before

        let buttons = [];
        let createButton = (textContent, handleClick) => {
            let button = treeElement.title.appendChild(document.createElement("button"));
            button.textContent = textContent;
            button.addEventListener("click", (event) => {
                event.stop();

                representation.singleFireEventListener(ObjectTreeView.Event.Updated, () => {
                    // The `treeElement` may have already been removed by some other means (e.g. `removeChildren`).
                    if (treeElement.parent === parentTreeElement)
                        parentTreeElement.removeChild(treeElement);
                });

                for (let other of buttons)
                    other.disabled = true;

                let spinner = new WI.IndeterminateProgressSpinner;
                buttons.lastValue.insertAdjacentElement("afterend", spinner.element);

                handleClick();
            });
            buttons.push(button);
        };

        if (!resolvedValue.isWeakCollection() && remaining > ObjectTreeView.showMoreFetchCount) {
            createButton(WI.UIString("Show %d More").format(ObjectTreeView.showMoreFetchCount), () => {
                representation._fetchStart = representation._fetchEnd;
                representation._fetchEnd = representation._fetchStart + ObjectTreeView.showMoreFetchCount;
                handleShowMoreClicked();
            });
        }

        createButton(WI.UIString("Show All (%d More)").format(remaining), () => {
            representation._fetchStart = 0;
            representation._fetchEnd = Infinity;
            representation._fetchEndIndex = 0;
            handleShowAllClicked();
        });
    }

    static comparePropertyDescriptors(propertyA, propertyB)
    {
        var a = propertyA.name;
        var b = propertyB.name;

        // Put __proto__ at the bottom.
        if (a === "__proto__")
            return 1;
        if (b === "__proto__")
            return -1;

        // Put Internal properties at the top.
        if (propertyA.isInternalProperty && !propertyB.isInternalProperty)
            return -1;
        if (propertyB.isInternalProperty && !propertyA.isInternalProperty)
            return 1;

        // Put Symbol properties at the bottom.
        if (propertyA.symbol && !propertyB.symbol)
            return 1;
        if (propertyB.symbol && !propertyA.symbol)
            return -1;

        // Symbol properties may have the same description string but be different objects.
        if (a === b)
            return 0;

        var diff = 0;
        var chunk = /^\d+|^\D+/;
        var chunka, chunkb, anum, bnum;
        while (diff === 0) {
            if (!a && b)
                return -1;
            if (!b && a)
                return 1;
            chunka = a.match(chunk)[0];
            chunkb = b.match(chunk)[0];
            anum = !isNaN(chunka);
            bnum = !isNaN(chunkb);
            if (anum && !bnum)
                return -1;
            if (bnum && !anum)
                return 1;
            if (anum && bnum) {
                diff = chunka - chunkb;
                if (diff === 0 && chunka.length !== chunkb.length) {
                    if (!+chunka && !+chunkb) // chunks are strings of all 0s (special case)
                        return chunka.length - chunkb.length;
                    else
                        return chunkb.length - chunka.length;
                }
            } else if (chunka !== chunkb)
                return chunka < chunkb ? -1 : 1;
            a = a.substring(chunka.length);
            b = b.substring(chunkb.length);
        }
        return diff;
    }

    // Public

    get object()
    {
        return this._object;
    }

    get element()
    {
        return this._element;
    }

    get treeOutline()
    {
        return this._outline;
    }

    get expanded()
    {
        return this._expanded;
    }

    expand()
    {
        if (this._expanded)
            return;

        if (this._hasLosslessPreview)
            return;

        this._expanded = true;
        this._element.classList.add("expanded");

        if (this._previewView)
            this._previewView.showTitle();

        this._trackWeakEntries();

        this.update();
    }

    collapse()
    {
        if (!this._expanded)
            return;

        this._expanded = false;
        this._element.classList.remove("expanded");

        if (this._previewView)
            this._previewView.showPreview();

        this._untrackWeakEntries();
    }

    showOnlyProperties()
    {
        this._inConsole = false;

        this._element.classList.add("properties-only");

        this._includeProtoProperty = false;
    }

    showOnlyJSON()
    {
        this.showOnlyProperties();

        this._element.classList.add("json-only");
    }

    appendTitleSuffix(suffixElement)
    {
        if (this._previewView)
            this._previewView.element.appendChild(suffixElement);
        else
            this._titleElement.appendChild(suffixElement);
    }

    appendExtraPropertyDescriptor(propertyDescriptor)
    {
        if (!this._extraProperties)
            this._extraProperties = [];

        this._extraProperties.push(propertyDescriptor);
    }

    setPrototypeNameOverride(override)
    {
        this._prototypeNameOverride = override;
    }

    // Protected

    update()
    {
        this._fetchStart = 0;
        this._fetchEndIndex = 0;
        this._updateChildren();
    }

    // Private

    _updateChildren()
    {
        let options = {
            ownProperties: true,
            generatePreview: true,
        };

        if (isFinite(this._fetchEnd) && this._fetchEnd < this._object.size) {
            options.fetchStart = this._fetchStart;
            options.fetchCount = this._fetchEnd - this._fetchStart;
        }

        let wrap = (handler) => (list) => {
            if (this._fetchEndIndex === 0)
                this._outline.removeChildren();

            if (!list) {
                let errorMessageElement = WI.ObjectTreeView.createEmptyMessageElement(WI.UIString("Could not fetch properties. Object may no longer exist."));
                this._outline.appendChild(new WI.TreeElement(errorMessageElement));
                return;
            }

            handler.call(this, list, this._propertyPath);

            this.dispatchEventToListeners(ObjectTreeView.Event.Updated);
        };

        if (this._object.isCollectionType() && this._mode === ObjectTreeView.Mode.Properties)
            this._object.getCollectionEntries(wrap(this._updateEntries), options);
        else if (this._object.isClass())
            this._object.classPrototype.getDisplayablePropertyDescriptors(wrap(this._updateProperties), options);
        else if (this._mode === ObjectTreeView.Mode.PureAPI)
            this._object.getPropertyDescriptors(wrap(this._updateProperties), options);
        else
            this._object.getDisplayablePropertyDescriptors(wrap(this._updateProperties), options);
    }

    _updateEntries(entries, propertyPath)
    {
        entries.forEach((entry, i) => {
            if (entry.key) {
                this._outline.insertChild(new WI.ObjectTreeMapKeyTreeElement(entry.key, propertyPath), this._fetchEndIndex++);
                this._outline.insertChild(new WI.ObjectTreeMapValueTreeElement(entry.value, propertyPath, entry.key), this._fetchEndIndex++);
            } else
                this._outline.insertChild(new WI.ObjectTreeSetIndexTreeElement(entry.value, propertyPath), this._fetchEndIndex++);
        });

        if (!this._outline.children.length) {
            let emptyMessageElement = ObjectTreeView.createEmptyMessageElement(WI.UIString("No Entries"));
            this._outline.appendChild(new WI.TreeElement(emptyMessageElement));
        } else {
            console.assert(this._mode === WI.ObjectTreeView.Mode.Properties);
            ObjectTreeView.addShowMoreIfNeeded({
                resolvedValue: this._object,
                representation: this,
                parentTreeElement: this._outline,
                handleShowMoreClicked: () => {
                    this._updateChildren();
                },
                handleShowAllClicked: () => {
                    this.update();
                },
            });
        }

        // Show the prototype so users can see the API, but only fetch it the first time.
        if (this._fetchStart === 0) {
            this._object.getOwnPropertyDescriptor("__proto__", (propertyDescriptor) => {
                if (propertyDescriptor)
                    this._outline.appendChild(new WI.ObjectTreePropertyTreeElement(propertyDescriptor, propertyPath, this._mode));
            });
        }
    }

    _updateProperties(properties, propertyPath)
    {
        if (this._extraProperties)
            properties.pushAll(this._extraProperties);

        properties.sort(WI.ObjectTreeView.comparePropertyDescriptors);

        var isArray = this._object.isArray();
        var isPropertyMode = this._mode === WI.ObjectTreeView.Mode.Properties;

        var hadProto = false;
        for (var propertyDescriptor of properties) {
            if (propertyDescriptor.name === "__proto__") {
                // COMPATIBILITY (iOS 8): Sometimes __proto__ is not a value, but a get/set property.
                // In those cases it is actually not useful to show.
                if (!propertyDescriptor.hasValue())
                    continue;
                if (!this._includeProtoProperty)
                    continue;
                hadProto = true;
                this._outline.appendChild(new WI.ObjectTreePropertyTreeElement(propertyDescriptor, propertyPath, this._mode, this._prototypeNameOverride));
                continue;
            }

            if (isArray && isPropertyMode) {
                if (propertyDescriptor.isIndexProperty())
                    this._outline.insertChild(new WI.ObjectTreeArrayIndexTreeElement(propertyDescriptor, propertyPath), this._fetchEndIndex++);
            } else
                this._outline.insertChild(new WI.ObjectTreePropertyTreeElement(propertyDescriptor, propertyPath, this._mode, this._prototypeNameOverride), this._fetchEndIndex++);
        }

        if (!this._outline.children.length || (hadProto && this._outline.children.length === 1)) {
            let emptyMessageElement = ObjectTreeView.createEmptyMessageElement(WI.UIString("No Properties"));
            this._outline.insertChild(new WI.TreeElement(emptyMessageElement), 0);
        } else if (isArray && isPropertyMode) {
            ObjectTreeView.addShowMoreIfNeeded({
                resolvedValue: this._object,
                representation: this,
                parentTreeElement: this._outline,
                handleShowMoreClicked: () => {
                    this._updateChildren();
                },
                handleShowAllClicked: () => {
                    this.update();
                },
            });
        }
    }

    _handlePreviewOrTitleElementClick(event)
    {
        if (this._hasLosslessPreview)
            return;

        if (!this._expanded)
            this.expand();
        else
            this.collapse();

        event.stopPropagation();
    }

    _trackWeakEntries()
    {
        if (this._trackingEntries)
            return;

        if (!this._object.isWeakCollection())
            return;

        this._trackingEntries = true;

        if (this._inConsole) {
            WI.consoleManager.addEventListener(WI.ConsoleManager.Event.Cleared, this._untrackWeakEntries, this);
            WI.consoleManager.addEventListener(WI.ConsoleManager.Event.SessionStarted, this._untrackWeakEntries, this);
        }
    }

    _untrackWeakEntries()
    {
        if (!this._trackingEntries)
            return;

        if (!this._object.isWeakCollection())
            return;

        this._trackingEntries = false;

        this._object.releaseWeakCollectionEntries();

        if (this._inConsole) {
            WI.consoleManager.removeEventListener(WI.ConsoleManager.Event.Cleared, this._untrackWeakEntries, this);
            WI.consoleManager.removeEventListener(WI.ConsoleManager.Event.SessionStarted, this._untrackWeakEntries, this);
        }

        // FIXME: This only tries to release weak entries if this object was a WeakMap.
        // If there was a WeakMap expanded in a sub-object, we will never release those values.
        // Should we attempt walking the entire tree and release weak collections?
    }
};

WI.ObjectTreeView.Mode = {
    Properties: Symbol("object-tree-properties"),      // Properties
    PrototypeAPI: Symbol("object-tree-prototype-api"), // API view on a live object instance, so getters can be invoked.
    ClassAPI: Symbol("object-tree-class-api"),         // API view without an object instance, can not invoke getters.
    PureAPI: Symbol("object-tree-pure-api"),           // API view without special displayable property handling, just own properties. Getters can be invoked if the property path has a non-prototype object.
};

WI.ObjectTreeView.Event = {
    Updated: "object-tree-updated",
};
