/*
 * 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.FormattedValue = {};

WI.FormattedValue.hasSimpleDisplay = function(object)
{
    switch (object.type) {
    case "boolean":
    case "number":
    case "string":
    case "symbol":
    case "undefined":
        return true;

    case "function":
        return false;

    case "object":
        var subtype = object.subtype;
        return subtype === "null" || subtype === "regexp" || subtype === "date";
    }

    console.assert(false, "All RemoteObject types should be handled above");
    return false;
};

WI.FormattedValue.classNameForTypes = function(type, subtype)
{
    return "formatted-" + (subtype ? subtype : type);
};

WI.FormattedValue.classNameForObject = function(object)
{
    return WI.FormattedValue.classNameForTypes(object.type, object.subtype);
};

WI.FormattedValue.createLinkifiedElementString = function(string)
{
    var span = document.createElement("span");
    span.className = "formatted-string";
    span.append("\"", WI.linkifyStringAsFragment(string.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")), "\"");
    return span;
};

WI.FormattedValue.createElementForNode = function(object)
{
    var span = document.createElement("span");
    span.className = "formatted-node";

    object.pushNodeToFrontend(function(nodeId) {
        if (!nodeId) {
            span.textContent = object.description;
            return;
        }

        var treeOutline = new WI.DOMTreeOutline;
        treeOutline.setVisible(true);
        treeOutline.rootDOMNode = WI.domManager.nodeForId(nodeId);
        if (!treeOutline.children[0].hasChildren)
            treeOutline.element.classList.add("single-node");
        span.appendChild(treeOutline.element);
    });

    return span;
};

WI.FormattedValue.createElementForError = function(object)
{
    var span = document.createElement("span");
    span.classList.add("formatted-error");
    span.textContent = object.description;

    if (!object.preview)
        return span;

    function previewToObject(preview)
    {
        var result = {};
        for (var property of preview.propertyPreviews)
            result[property.name] = property.value;

        return result;
    }

    var preview = previewToObject(object.preview);
    if (!preview.sourceURL)
        return span;

    var sourceLinkWithPrefix = WI.ErrorObjectView.makeSourceLinkWithPrefix(preview.sourceURL, preview.line, preview.column);
    span.append(sourceLinkWithPrefix);
    return span;
};

WI.FormattedValue.createElementForNodePreview = function(preview, {remoteObjectAccessor} = {})
{
    var value = preview.value || preview.description;
    var span = document.createElement("span");
    span.className = "formatted-node-preview syntax-highlighted";

    if (remoteObjectAccessor) {
        let domNode = null;

        span.addEventListener("mouseenter", (event) => {
            if (domNode) {
                WI.domManager.highlightDOMNode(domNode.id, "all");
                return;
            }

            remoteObjectAccessor((remoteObject) => {
                remoteObject.pushNodeToFrontend((nodeId) => {
                    domNode = WI.domManager.nodeForId(nodeId);
                    if (domNode)
                        WI.domManager.highlightDOMNode(domNode.id, "all");
                });
            });
        });

        span.addEventListener("mouseleave", (event) => {
            WI.domManager.hideDOMNodeHighlight();
        });

        span.addEventListener("contextmenu", (event) => {
            if (!domNode)
                return;

            let contextMenu = WI.ContextMenu.createFromEvent(event);

            WI.appendContextMenuItemsForDOMNode(contextMenu, domNode);
        });
    }

    // Comment node preview.
    if (value.startsWith("<!--")) {
        var comment = span.appendChild(document.createElement("span"));
        comment.className = "html-comment";
        comment.textContent = value;
        return span;
    }

    // Doctype node preview.
    if (value.startsWith("<!DOCTYPE")) {
        var doctype = span.appendChild(document.createElement("span"));
        doctype.className = "html-doctype";
        doctype.textContent = value;
        return span;
    }

    // Element node previews have a very strict format, with at most a single attribute.
    // We can style it up like a DOMNode without interactivity.
    var matches = value.match(/^<(\S+?)(?: (\S+?)="(.*?)")?>$/);

    // Remaining node types are often #text, #document, etc, with attribute nodes potentially being any string.
    if (!matches) {
        console.assert(!value.startsWith("<"), "Unexpected node preview format: " + value);
        span.textContent = value;
        return span;
    }

    var tag = document.createElement("span");
    tag.className = "html-tag";
    tag.append("<");

    var tagName = tag.appendChild(document.createElement("span"));
    tagName.className = "html-tag-name";
    tagName.textContent = matches[1];

    if (matches[2]) {
        tag.append(" ");
        var attribute = tag.appendChild(document.createElement("span"));
        attribute.className = "html-attribute";
        var attributeName = attribute.appendChild(document.createElement("span"));
        attributeName.className = "html-attribute-name";
        attributeName.textContent = matches[2];
        attribute.append("=\"");
        var attributeValue = attribute.appendChild(document.createElement("span"));
        attributeValue.className = "html-attribute-value";
        attributeValue.textContent = matches[3];
        attribute.append("\"");
    }

    tag.append(">");
    span.appendChild(tag);

    return span;
};

WI.FormattedValue.createElementForFunctionWithName = function(description)
{
    var span = document.createElement("span");
    span.classList.add("formatted-function");
    span.textContent = description.substring(0, description.indexOf("("));
    return span;
};

WI.FormattedValue.createElementForTypesAndValue = function(type, subtype, displayString, size, isPreview, hadException)
{
    var span = document.createElement("span");
    span.classList.add(WI.FormattedValue.classNameForTypes(type, subtype));

    // Exception.
    if (hadException) {
        span.textContent = "[Exception: " + displayString + "]";
        return span;
    }

    // String: quoted and replace newlines as nice unicode symbols.
    if (type === "string") {
        displayString = displayString.truncate(WI.FormattedValue.MAX_PREVIEW_STRING_LENGTH);
        span.textContent = doubleQuotedString(displayString.replace(/\n/g, "\u21B5"));
        return span;
    }

    // Function: if class, show the description, otherwise elide in previews.
    if (type === "function") {
        if (subtype === "class")
            span.textContent = displayString;
        else
            span.textContent = isPreview ? "function" : displayString;
        return span;
    }

    // Everything else, the description/value string.
    span.textContent = displayString;

    // If there is a size, include it.
    if (size !== undefined && (subtype === "array" || subtype === "set" || subtype === "map" || subtype === "weakmap" || subtype === "weakset")) {
        var sizeElement = span.appendChild(document.createElement("span"));
        sizeElement.className = "size";
        sizeElement.textContent = " (" + size + ")";
    }

    return span;
};

WI.FormattedValue.createElementForRemoteObject = function(object, hadException)
{
    return WI.FormattedValue.createElementForTypesAndValue(object.type, object.subtype, object.description, object.size, false, hadException);
};

WI.FormattedValue.createElementForObjectPreview = function(objectPreview)
{
    return WI.FormattedValue.createElementForTypesAndValue(objectPreview.type, objectPreview.subtype, objectPreview.description, objectPreview.size, true, false);
};

WI.FormattedValue.createElementForPropertyPreview = function(propertyPreview)
{
    return WI.FormattedValue.createElementForTypesAndValue(propertyPreview.type, propertyPreview.subtype, propertyPreview.value, undefined, true, false);
};

WI.FormattedValue.createObjectPreviewOrFormattedValueForObjectPreview = function(objectPreview, previewViewMode)
{
    if (objectPreview.subtype === "node")
        return WI.FormattedValue.createElementForNodePreview(objectPreview);

    if (objectPreview.type === "function")
        return WI.FormattedValue.createElementForFunctionWithName(objectPreview.description);

    const object = null;
    return new WI.ObjectPreviewView(object, objectPreview, previewViewMode).element;
};

WI.FormattedValue.createObjectPreviewOrFormattedValueForRemoteObject = function(object, previewViewMode)
{
    if (object.subtype === "node")
        return WI.FormattedValue.createElementForNode(object);

    if (object.subtype === "error")
        return WI.FormattedValue.createElementForError(object);

    if (object.preview)
        return new WI.ObjectPreviewView(object, object.preview, previewViewMode);

    return WI.FormattedValue.createElementForRemoteObject(object);
};

WI.FormattedValue.createObjectTreeOrFormattedValueForRemoteObject = function(object, propertyPath, forceExpanding)
{
    if (object.subtype === "node")
        return WI.FormattedValue.createElementForNode(object);

    if (object.subtype === "null")
        return WI.FormattedValue.createElementForRemoteObject(object);

    if (object.type === "object" || object.subtype === "class") {
        var objectTree = new WI.ObjectTreeView(object, null, propertyPath, forceExpanding);
        return objectTree.element;
    }

    return WI.FormattedValue.createElementForRemoteObject(object);
};

WI.FormattedValue.MAX_PREVIEW_STRING_LENGTH = 140;
