/*
 * 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 "bigint":
    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;
