/*
 * Copyright (C) 2011 Google Inc.  All rights reserved.
 * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
 * Copyright (C) 2009 Joseph Pecoraro
 *
 * 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.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE 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 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.
 */

/**
 * @constructor
 * @implements {WebInspector.ViewportElement}
 * @param {!WebInspector.ConsoleMessage} consoleMessage
 * @param {!WebInspector.Linkifier} linkifier
 * @param {number} nestingLevel
 */
WebInspector.ConsoleViewMessage = function(consoleMessage, linkifier, nestingLevel)
{
    this._message = consoleMessage;
    this._linkifier = linkifier;
    this._repeatCount = 1;
    this._closeGroupDecorationCount = 0;
    this._nestingLevel = nestingLevel;

    /** @type {!Array.<!WebInspector.DataGrid>} */
    this._dataGrids = [];
    /** @type {!Map.<!WebInspector.DataGrid, ?Element>} */
    this._dataGridParents = new Map();

    /** @type {!Object.<string, function(!WebInspector.RemoteObject, !Element, boolean=)>} */
    this._customFormatters = {
        "array": this._formatParameterAsArray,
        "error": this._formatParameterAsError,
        "function": this._formatParameterAsFunction,
        "generator": this._formatParameterAsObject,
        "iterator": this._formatParameterAsObject,
        "map": this._formatParameterAsObject,
        "node": this._formatParameterAsNode,
        "object": this._formatParameterAsObject,
        "set": this._formatParameterAsObject,
        "string": this._formatParameterAsString
    };
    this._previewFormatter = new WebInspector.RemoteObjectPreviewFormatter();
    this._searchRegex = null;
}

WebInspector.ConsoleViewMessage.prototype = {
    /**
     * @return {?WebInspector.Target}
     */
    _target: function()
    {
        return this.consoleMessage().target();
    },

    /**
     * @override
     * @return {!Element}
     */
    element: function()
    {
        return this.toMessageElement();
    },

    /**
     * @override
     */
    wasShown: function()
    {
        for (var i = 0; this._dataGrids && i < this._dataGrids.length; ++i) {
            var dataGrid = this._dataGrids[i];
            var parentElement = this._dataGridParents.get(dataGrid) || null;
            dataGrid.show(parentElement);
            dataGrid.updateWidths();
        }
    },

    /**
     * @override
     */
    cacheFastHeight: function()
    {
        this._cachedHeight = this.contentElement().offsetHeight;
    },

    /**
     * @override
     */
    willHide: function()
    {
        for (var i = 0; this._dataGrids && i < this._dataGrids.length; ++i) {
            var dataGrid = this._dataGrids[i];
            this._dataGridParents.set(dataGrid, dataGrid.element.parentElement);
            dataGrid.detach();
        }
    },

    /**
     * @return {number}
     */
    fastHeight: function()
    {
        if (this._cachedHeight)
            return this._cachedHeight;
        const defaultConsoleRowHeight = 18;  // Sync with consoleView.css
        if (this._message.type === WebInspector.ConsoleMessage.MessageType.Table) {
            var table = this._message.parameters[0];
            if (table && table.preview)
                return defaultConsoleRowHeight * table.preview.properties.length;
        }
        return defaultConsoleRowHeight;
    },

    /**
     * @return {!WebInspector.ConsoleMessage}
     */
    consoleMessage: function()
    {
        return this._message;
    },

    _formatMessage: function()
    {
        this._formattedMessage = createElement("span");
        this._formattedMessage.appendChild(WebInspector.Widget.createStyleElement("components/objectValue.css"));
        this._formattedMessage.className = "console-message-text source-code";

        /**
         * @param {string} title
         * @return {!Element}
         * @this {WebInspector.ConsoleMessage}
         */
        function linkifyRequest(title)
        {
            return WebInspector.Linkifier.linkifyUsingRevealer(/** @type {!WebInspector.NetworkRequest} */ (this.request), title, this.request.url);
        }

        var consoleMessage = this._message;
        if (!this._messageElement) {
            if (consoleMessage.source === WebInspector.ConsoleMessage.MessageSource.ConsoleAPI) {
                switch (consoleMessage.type) {
                    case WebInspector.ConsoleMessage.MessageType.Trace:
                        this._messageElement = this._format(consoleMessage.parameters || ["console.trace()"]);
                        break;
                    case WebInspector.ConsoleMessage.MessageType.Clear:
                        this._messageElement = createTextNode(WebInspector.UIString("Console was cleared"));
                        this._formattedMessage.classList.add("console-info");
                        break;
                    case WebInspector.ConsoleMessage.MessageType.Assert:
                        var args = [WebInspector.UIString("Assertion failed:")];
                        if (consoleMessage.parameters)
                            args = args.concat(consoleMessage.parameters);
                        this._messageElement = this._format(args);
                        break;
                    case WebInspector.ConsoleMessage.MessageType.Dir:
                        var obj = consoleMessage.parameters ? consoleMessage.parameters[0] : undefined;
                        var args = ["%O", obj];
                        this._messageElement = this._format(args);
                        break;
                    case WebInspector.ConsoleMessage.MessageType.Profile:
                    case WebInspector.ConsoleMessage.MessageType.ProfileEnd:
                        this._messageElement = this._format([consoleMessage.messageText]);
                        break;
                    default:
                        if (consoleMessage.parameters && consoleMessage.parameters.length === 1 && consoleMessage.parameters[0].type === "string")
                             this._messageElement = this._tryFormatAsError(/**@type {string} */(consoleMessage.parameters[0].value));

                        var args = consoleMessage.parameters || [consoleMessage.messageText];
                        this._messageElement = this._messageElement || this._format(args);
                }
            } else if (consoleMessage.source === WebInspector.ConsoleMessage.MessageSource.Network) {
                if (consoleMessage.request) {
                    this._messageElement = createElement("span");
                    if (consoleMessage.level === WebInspector.ConsoleMessage.MessageLevel.Error || consoleMessage.level === WebInspector.ConsoleMessage.MessageLevel.RevokedError) {
                        this._messageElement.createTextChildren(consoleMessage.request.requestMethod, " ");
                        this._messageElement.appendChild(WebInspector.Linkifier.linkifyUsingRevealer(consoleMessage.request, consoleMessage.request.url, consoleMessage.request.url));
                        if (consoleMessage.request.failed)
                            this._messageElement.createTextChildren(" ", consoleMessage.request.localizedFailDescription);
                        else
                            this._messageElement.createTextChildren(" ", String(consoleMessage.request.statusCode), " (", consoleMessage.request.statusText, ")");
                    } else {
                        var fragment = WebInspector.linkifyStringAsFragmentWithCustomLinkifier(consoleMessage.messageText, linkifyRequest.bind(consoleMessage));
                        this._messageElement.appendChild(fragment);
                    }
                } else {
                    var url = consoleMessage.url;
                    if (url) {
                        var isExternal = !WebInspector.resourceForURL(url) && !WebInspector.networkMapping.uiSourceCodeForURLForAnyTarget(url);
                        this._anchorElement = WebInspector.linkifyURLAsNode(url, url, "console-message-url", isExternal);
                    }
                    this._messageElement = this._format([consoleMessage.messageText]);
                }
            } else {
                var args = consoleMessage.parameters || [consoleMessage.messageText];
                this._messageElement = this._format(args);
            }
        }

        if (consoleMessage.source !== WebInspector.ConsoleMessage.MessageSource.Network || consoleMessage.request) {
            if (consoleMessage.scriptId) {
                this._anchorElement = this._linkifyScriptId(consoleMessage.scriptId, consoleMessage.url || "", consoleMessage.line, consoleMessage.column);
            } else {
                var showBlackboxed = (consoleMessage.source !== WebInspector.ConsoleMessage.MessageSource.ConsoleAPI);
                var debuggerModel = WebInspector.DebuggerModel.fromTarget(this._target());
                var callFrame = WebInspector.DebuggerPresentationUtils.callFrameAnchorFromStackTrace(debuggerModel, consoleMessage.stackTrace, consoleMessage.asyncStackTrace, showBlackboxed);
                if (callFrame && callFrame.scriptId)
                    this._anchorElement = this._linkifyCallFrame(callFrame);
                else if (consoleMessage.url && consoleMessage.url !== "undefined")
                    this._anchorElement = this._linkifyLocation(consoleMessage.url, consoleMessage.line, consoleMessage.column);
            }
        }

        this._formattedMessage.appendChild(this._messageElement);
        if (this._anchorElement) {
            // Append a space to prevent the anchor text from being glued to the console message when the user selects and copies the console messages.
            this._anchorElement.appendChild(createTextNode(" "));
            this._formattedMessage.insertBefore(this._anchorElement, this._formattedMessage.firstChild);
        }

        var dumpStackTrace = !!consoleMessage.stackTrace && consoleMessage.stackTrace.length && (consoleMessage.source === WebInspector.ConsoleMessage.MessageSource.Network || consoleMessage.level === WebInspector.ConsoleMessage.MessageLevel.Error || consoleMessage.level === WebInspector.ConsoleMessage.MessageLevel.RevokedError || consoleMessage.type === WebInspector.ConsoleMessage.MessageType.Trace);
        if (dumpStackTrace) {
            var treeOutline = new TreeOutline();
            treeOutline.element.classList.add("outline-disclosure", "outline-disclosure-no-padding");
            var content = this._formattedMessage;
            var root = new TreeElement(content);
            root.toggleOnClick = true;
            root.selectable = false;
            content.treeElementForTest = root;
            treeOutline.appendChild(root);
            if (consoleMessage.type === WebInspector.ConsoleMessage.MessageType.Trace)
                root.expand();

            this._populateStackTraceTreeElement(root);
            this._formattedMessage = treeOutline.element;
        }
    },

    /**
     * @return {!Element}
     */
    formattedMessage: function()
    {
        if (!this._formattedMessage)
            this._formatMessage();
        return this._formattedMessage;
    },

    /**
     * @param {string} url
     * @param {number} lineNumber
     * @param {number} columnNumber
     * @return {?Element}
     */
    _linkifyLocation: function(url, lineNumber, columnNumber)
    {
        var target = this._target();
        if (!target)
            return null;
        // FIXME(62725): stack trace line/column numbers are one-based.
        lineNumber = lineNumber ? lineNumber - 1 : 0;
        columnNumber = columnNumber ? columnNumber - 1 : 0;
        return this._linkifier.linkifyScriptLocation(target, null, url, lineNumber, columnNumber, "console-message-url");
    },

    /**
     * @param {!ConsoleAgent.CallFrame} callFrame
     * @return {?Element}
     */
    _linkifyCallFrame: function(callFrame)
    {
        var target = this._target();
        return this._linkifier.linkifyConsoleCallFrame(target, callFrame, "console-message-url");
    },

    /**
     * @param {string} scriptId
     * @param {string} url
     * @param {number} lineNumber
     * @param {number} columnNumber
     * @return {?Element}
     */
    _linkifyScriptId: function(scriptId, url, lineNumber, columnNumber)
    {
        var target = this._target();
        if (!target)
            return null;
        // FIXME(62725): stack trace line/column numbers are one-based.
        lineNumber = lineNumber ? lineNumber - 1 : 0;
        columnNumber = columnNumber ? columnNumber - 1 : 0;
        return this._linkifier.linkifyScriptLocation(target, scriptId, url, lineNumber, columnNumber, "console-message-url");
    },

    _format: function(parameters)
    {
        // This node is used like a Builder. Values are continually appended onto it.
        var formattedResult = createElement("span");
        if (!parameters.length)
            return formattedResult;

        var target = this._target();

        // Formatting code below assumes that parameters are all wrappers whereas frontend console
        // API allows passing arbitrary values as messages (strings, numbers, etc.). Wrap them here.
        for (var i = 0; i < parameters.length; ++i) {
            // FIXME: Only pass runtime wrappers here.
            if (parameters[i] instanceof WebInspector.RemoteObject)
                continue;

            if (!target) {
                parameters[i] = WebInspector.RemoteObject.fromLocalObject(parameters[i]);
                continue;
            }

            if (typeof parameters[i] === "object")
                parameters[i] = target.runtimeModel.createRemoteObject(parameters[i]);
            else
                parameters[i] = target.runtimeModel.createRemoteObjectFromPrimitiveValue(parameters[i]);
        }

        // There can be string log and string eval result. We distinguish between them based on message type.
        var shouldFormatMessage = WebInspector.RemoteObject.type(parameters[0]) === "string" && (this._message.type !== WebInspector.ConsoleMessage.MessageType.Result || this._message.level === WebInspector.ConsoleMessage.MessageLevel.Error || this._message.level === WebInspector.ConsoleMessage.MessageLevel.RevokedError);

        // Multiple parameters with the first being a format string. Save unused substitutions.
        if (shouldFormatMessage) {
            // Multiple parameters with the first being a format string. Save unused substitutions.
            var result = this._formatWithSubstitutionString(parameters[0].description, parameters.slice(1), formattedResult);
            parameters = result.unusedSubstitutions;
            if (parameters.length)
                formattedResult.createTextChild(" ");
        }

        if (this._message.type === WebInspector.ConsoleMessage.MessageType.Table) {
            formattedResult.appendChild(this._formatParameterAsTable(parameters));
            return formattedResult;
        }

        // Single parameter, or unused substitutions from above.
        for (var i = 0; i < parameters.length; ++i) {
            // Inline strings when formatting.
            if (shouldFormatMessage && parameters[i].type === "string")
                formattedResult.appendChild(WebInspector.linkifyStringAsFragment(parameters[i].description));
            else
                formattedResult.appendChild(this._formatParameter(parameters[i], false, true));
            if (i < parameters.length - 1)
                formattedResult.createTextChild(" ");
        }
        return formattedResult;
    },

    /**
     * @param {!WebInspector.RemoteObject} output
     * @param {boolean=} forceObjectFormat
     * @param {boolean=} includePreview
     * @return {!Element}
     */
    _formatParameter: function(output, forceObjectFormat, includePreview)
    {
        if (output.customPreview()) {
            return (new WebInspector.CustomPreviewComponent(output)).element;
        }

        var type = forceObjectFormat ? "object" : (output.subtype || output.type);
        var formatter = this._customFormatters[type] || this._formatParameterAsValue;
        var span = createElement("span");
        span.className = "object-value-" + type + " source-code";
        formatter.call(this, output, span, includePreview);
        return span;
    },

    /**
     * @param {!WebInspector.RemoteObject} obj
     * @param {!Element} elem
     */
    _formatParameterAsValue: function(obj, elem)
    {
        elem.createTextChild(obj.description || "");
        if (obj.objectId)
            elem.addEventListener("contextmenu", this._contextMenuEventFired.bind(this, obj), false);
    },

    /**
     * @param {!WebInspector.RemoteObject} obj
     * @param {!Element} elem
     * @param {boolean=} includePreview
     */
    _formatParameterAsObject: function(obj, elem, includePreview)
    {
        this._formatParameterAsArrayOrObject(obj, elem, includePreview);
    },

    /**
     * @param {!WebInspector.RemoteObject} obj
     * @param {!Element} elem
     * @param {boolean=} includePreview
     */
    _formatParameterAsArrayOrObject: function(obj, elem, includePreview)
    {
        var titleElement = createElement("span");
        if (includePreview && obj.preview) {
            titleElement.classList.add("console-object-preview");
            var lossless = this._previewFormatter.appendObjectPreview(titleElement, obj.preview);
            if (lossless) {
                elem.appendChild(titleElement);
                titleElement.addEventListener("contextmenu", this._contextMenuEventFired.bind(this, obj), false);
                return;
            }
        } else {
            if (obj.type === "function") {
                WebInspector.ObjectPropertiesSection.formatObjectAsFunction(obj, titleElement, false);
                titleElement.classList.add("object-value-function");
            } else {
                titleElement.createTextChild(obj.description || "");
            }
        }
        var note = titleElement.createChild("span", "object-info-state-note");
        note.title = WebInspector.UIString("Object state below is captured upon first expansion");
        var section = new WebInspector.ObjectPropertiesSection(obj, titleElement);
        section.enableContextMenu();
        elem.appendChild(section.element);
        section.element.classList.add("console-view-object-properties-section");
    },

    /**
     * @param {!WebInspector.RemoteObject} func
     * @param {!Element} element
     * @param {boolean=} includePreview
     */
    _formatParameterAsFunction: function(func, element, includePreview)
    {
        WebInspector.ObjectPropertiesSection.formatObjectAsFunction(func, element, true, includePreview);
        element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this, func), false);
    },

    /**
     * @param {!WebInspector.RemoteObject} obj
     * @param {!Event} event
     */
    _contextMenuEventFired: function(obj, event)
    {
        var contextMenu = new WebInspector.ContextMenu(event);
        contextMenu.appendApplicableItems(obj);
        contextMenu.show();
    },

    /**
     * @param {?WebInspector.RemoteObject} object
     * @param {!Array.<!RuntimeAgent.PropertyPreview>} propertyPath
     * @return {!Element}
     */
    _renderPropertyPreviewOrAccessor: function(object, propertyPath)
    {
        var property = propertyPath.peekLast();
        if (property.type === "accessor")
            return this._formatAsAccessorProperty(object, propertyPath.select("name"), false);
        return this._previewFormatter.renderPropertyPreview(property.type, /** @type {string} */ (property.subtype), property.value);
    },

    /**
     * @param {!WebInspector.RemoteObject} object
     * @param {!Element} elem
     */
    _formatParameterAsNode: function(object, elem)
    {
        WebInspector.Renderer.renderPromise(object).then(appendRenderer, failedToRender.bind(this));
        /**
         * @param {!Element} rendererElement
         */
        function appendRenderer(rendererElement)
        {
            elem.appendChild(rendererElement);
        }

        /**
         * @this {WebInspector.ConsoleViewMessage}
         */
        function failedToRender()
        {
            this._formatParameterAsObject(object, elem, false);
        }
    },

    /**
     * @param {!WebInspector.RemoteObject} array
     * @return {boolean}
     */
    useArrayPreviewInFormatter: function(array)
    {
        return this._message.type !== WebInspector.ConsoleMessage.MessageType.DirXML;
    },

    /**
     * @param {!WebInspector.RemoteObject} array
     * @param {!Element} elem
     */
    _formatParameterAsArray: function(array, elem)
    {
        var maxFlatArrayLength = 100;
        if (this.useArrayPreviewInFormatter(array) || array.arrayLength() > maxFlatArrayLength)
            this._formatParameterAsArrayOrObject(array, elem, this.useArrayPreviewInFormatter(array) || array.arrayLength() <= maxFlatArrayLength);
        else
            array.getAllProperties(false, this._printArray.bind(this, array, elem));
    },

    /**
     * @param {!Array.<!WebInspector.RemoteObject>} parameters
     * @return {!Element}
     */
    _formatParameterAsTable: function(parameters)
    {
        var element = createElementWithClass("div", "console-message-formatted-table");
        var table = parameters[0];
        if (!table || !table.preview)
            return element;

        var columnNames = [];
        var preview = table.preview;
        var rows = [];
        for (var i = 0; i < preview.properties.length; ++i) {
            var rowProperty = preview.properties[i];
            var rowPreview = rowProperty.valuePreview;
            if (!rowPreview)
                continue;

            var rowValue = {};
            const maxColumnsToRender = 20;
            for (var j = 0; j < rowPreview.properties.length; ++j) {
                var cellProperty = rowPreview.properties[j];
                var columnRendered = columnNames.indexOf(cellProperty.name) != -1;
                if (!columnRendered) {
                    if (columnNames.length === maxColumnsToRender)
                        continue;
                    columnRendered = true;
                    columnNames.push(cellProperty.name);
                }

                if (columnRendered) {
                    var cellElement = this._renderPropertyPreviewOrAccessor(table, [rowProperty, cellProperty]);
                    cellElement.classList.add("console-message-nowrap-below");
                    rowValue[cellProperty.name] = cellElement;
                }
            }
            rows.push([rowProperty.name, rowValue]);
        }

        var flatValues = [];
        for (var i = 0; i < rows.length; ++i) {
            var rowName = rows[i][0];
            var rowValue = rows[i][1];
            flatValues.push(rowName);
            for (var j = 0; j < columnNames.length; ++j)
                flatValues.push(rowValue[columnNames[j]]);
        }

        var dataGridContainer = element.createChild("span");
        if (!preview.lossless || !flatValues.length) {
            element.appendChild(this._formatParameter(table, true, false));
            if (!flatValues.length)
                return element;
        }

        columnNames.unshift(WebInspector.UIString("(index)"));
        var dataGrid = WebInspector.SortableDataGrid.create(columnNames, flatValues);
        dataGrid.renderInline();
        this._dataGrids.push(dataGrid);
        this._dataGridParents.set(dataGrid, dataGridContainer);
        return element;
    },

    /**
     * @param {!WebInspector.RemoteObject} output
     * @param {!Element} elem
     */
    _formatParameterAsString: function(output, elem)
    {
        var span = createElement("span");
        span.className = "object-value-string source-code";
        span.appendChild(WebInspector.linkifyStringAsFragment(output.description || ""));

        // Make black quotes.
        elem.classList.remove("object-value-string");
        elem.createTextChild("\"");
        elem.appendChild(span);
        elem.createTextChild("\"");
    },

    /**
     * @param {!WebInspector.RemoteObject} output
     * @param {!Element} elem
     */
    _formatParameterAsError: function(output, elem)
    {
        var span = elem.createChild("span", "object-value-error source-code");
        var text = output.description || "";
        var lines = text.split("\n", 2);
        span.appendChild(WebInspector.linkifyStringAsFragment(lines[0]));
        if (lines.length > 1) {
            var detailedLink = elem.createChild("a");
            detailedLink.textContent = "(\u2026)";
            function showDetailed(event)
            {
                span.removeChildren();
                detailedLink.remove();
                span.appendChild(WebInspector.linkifyStringAsFragment(text));
                event.consume(true);
            }
            detailedLink._showDetailedForTest = showDetailed.bind(null, new MouseEvent('click'));
            detailedLink.addEventListener("click", showDetailed, false);
        }
    },

    /**
     * @param {!WebInspector.RemoteObject} array
     * @param {!Element} elem
     * @param {?Array.<!WebInspector.RemoteObjectProperty>} properties
     */
    _printArray: function(array, elem, properties)
    {
        if (!properties) {
            this._formatParameterAsObject(array, elem, false);
            return;
        }

        var elements = [];
        for (var i = 0; i < properties.length; ++i) {
            var property = properties[i];
            var name = property.name;
            if (isNaN(name))
                continue;
            if (property.getter)
                elements[name] = this._formatAsAccessorProperty(array, [name], true);
            else if (property.value)
                elements[name] = this._formatAsArrayEntry(property.value);
        }

        elem.createTextChild("[");
        var lastNonEmptyIndex = -1;

        function appendUndefined(elem, index)
        {
            if (index - lastNonEmptyIndex <= 1)
                return;
            var span = elem.createChild("span", "object-value-undefined");
            span.textContent = WebInspector.UIString("undefined × %d", index - lastNonEmptyIndex - 1);
        }

        var length = array.arrayLength();
        for (var i = 0; i < length; ++i) {
            var element = elements[i];
            if (!element)
                continue;

            if (i - lastNonEmptyIndex > 1) {
                appendUndefined(elem, i);
                elem.createTextChild(", ");
            }

            elem.appendChild(element);
            lastNonEmptyIndex = i;
            if (i < length - 1)
                elem.createTextChild(", ");
        }
        appendUndefined(elem, length);

        elem.createTextChild("]");
        elem.addEventListener("contextmenu", this._contextMenuEventFired.bind(this, array), false);
    },

    /**
     * @param {!WebInspector.RemoteObject} output
     * @return {!Element}
     */
    _formatAsArrayEntry: function(output)
    {
        // Prevent infinite expansion of cross-referencing arrays.
        return this._formatParameter(output, output.subtype === "array", false);
    },

    /**
     * @param {?WebInspector.RemoteObject} object
     * @param {!Array.<string>} propertyPath
     * @param {boolean} isArrayEntry
     * @return {!Element}
     */
    _formatAsAccessorProperty: function(object, propertyPath, isArrayEntry)
    {
        var rootElement = WebInspector.ObjectPropertyTreeElement.createRemoteObjectAccessorPropertySpan(object, propertyPath, onInvokeGetterClick.bind(this));

        /**
         * @param {?WebInspector.RemoteObject} result
         * @param {boolean=} wasThrown
         * @this {WebInspector.ConsoleViewMessage}
         */
        function onInvokeGetterClick(result, wasThrown)
        {
            if (!result)
                return;
            rootElement.removeChildren();
            if (wasThrown) {
                var element = rootElement.createChild("span", "error-message");
                element.textContent = WebInspector.UIString("<exception>");
                element.title = /** @type {string} */ (result.description);
            } else if (isArrayEntry) {
                rootElement.appendChild(this._formatAsArrayEntry(result));
            } else {
                // Make a PropertyPreview from the RemoteObject similar to the backend logic.
                const maxLength = 100;
                var type = result.type;
                var subtype = result.subtype;
                var description = "";
                if (type !== "function" && result.description) {
                    if (type === "string" || subtype === "regexp")
                        description = result.description.trimMiddle(maxLength);
                    else
                        description = result.description.trimEnd(maxLength);
                }
                rootElement.appendChild(this._previewFormatter.renderPropertyPreview(type, subtype, description));
            }
        }

        return rootElement;
    },

    /**
     * @param {string} format
     * @param {!Array.<string>} parameters
     * @param {!Element} formattedResult
     */
    _formatWithSubstitutionString: function(format, parameters, formattedResult)
    {
        var formatters = {};

        /**
         * @param {boolean} force
         * @param {!WebInspector.RemoteObject} obj
         * @return {!Element}
         * @this {WebInspector.ConsoleViewMessage}
         */
        function parameterFormatter(force, obj)
        {
            return this._formatParameter(obj, force, false);
        }

        function stringFormatter(obj)
        {
            return obj.description;
        }

        function floatFormatter(obj)
        {
            if (typeof obj.value !== "number")
                return "NaN";
            return obj.value;
        }

        function integerFormatter(obj)
        {
            if (typeof obj.value !== "number")
                return "NaN";
            return Math.floor(obj.value);
        }

        function bypassFormatter(obj)
        {
            return (obj instanceof Node) ? obj : "";
        }

        var currentStyle = null;
        function styleFormatter(obj)
        {
            currentStyle = {};
            var buffer = createElement("span");
            buffer.setAttribute("style", obj.description);
            for (var i = 0; i < buffer.style.length; i++) {
                var property = buffer.style[i];
                var value = buffer.style.getPropertyValue(property);
                if (!value.startsWith("url(") && isWhitelistedProperty(property))
                    currentStyle[property] = buffer.style[property];
            }
        }

        function isWhitelistedProperty(property)
        {
            var prefixes = ["background", "border", "color", "font", "line", "margin", "padding", "text", "-webkit-background", "-webkit-border", "-webkit-font", "-webkit-margin", "-webkit-padding", "-webkit-text"];
            for (var i = 0; i < prefixes.length; i++) {
                if (property.startsWith(prefixes[i]))
                    return true;
            }
            return false;
        }

        // Firebug uses %o for formatting objects.
        formatters.o = parameterFormatter.bind(this, false);
        formatters.s = stringFormatter;
        formatters.f = floatFormatter;
        // Firebug allows both %i and %d for formatting integers.
        formatters.i = integerFormatter;
        formatters.d = integerFormatter;

        // Firebug uses %c for styling the message.
        formatters.c = styleFormatter;

        // Support %O to force object formatting, instead of the type-based %o formatting.
        formatters.O = parameterFormatter.bind(this, true);

        formatters._ = bypassFormatter;

        function append(a, b)
        {
            if (b instanceof Node)
                a.appendChild(b);
            else if (typeof b !== "undefined") {
                var toAppend = WebInspector.linkifyStringAsFragment(String(b));
                if (currentStyle) {
                    var wrapper = createElement('span');
                    wrapper.appendChild(toAppend);
                    applyCurrentStyle(wrapper);
                    for (var i = 0; i < wrapper.children.length; ++i)
                        applyCurrentStyle(wrapper.children[i]);
                    toAppend = wrapper;
                }
                a.appendChild(toAppend);
            }
            return a;
        }

        /**
         * @param {!Element} element
         */
        function applyCurrentStyle(element)
        {
            for (var key in currentStyle)
                element.style[key] = currentStyle[key];
        }

        // String.format does treat formattedResult like a Builder, result is an object.
        return String.format(format, parameters, formatters, formattedResult, append);
    },

    /**
     * @return {boolean}
     */
    matchesFilterRegex: function(regexObject)
    {
        regexObject.lastIndex = 0;
        var text = this.searchableElement().deepTextContent();
        if (this._anchorElement)
            text += " " + this._anchorElement.textContent;
        return regexObject.test(text);
    },

    /**
     * @param {boolean} show
     */
    updateTimestamp: function(show)
    {
        if (!this._formattedMessage)
            return;

        if (show && !this.timestampElement) {
            this.timestampElement = createElementWithClass("span", "console-timestamp");
            this.timestampElement.textContent = (new Date(this._message.timestamp)).toConsoleTime() + " ";
            var afterRepeatCountChild = this._repeatCountElement && this._repeatCountElement.nextSibling;
            this._formattedMessage.insertBefore(this.timestampElement, this._formattedMessage.firstChild);
            return;
        }

        if (!show && this.timestampElement) {
            this.timestampElement.remove();
            delete this.timestampElement;
        }
    },

    /**
     * @return {number}
     */
    nestingLevel: function()
    {
        return this._nestingLevel;
    },

    resetCloseGroupDecorationCount: function()
    {
        if (!this._closeGroupDecorationCount)
            return;
        this._closeGroupDecorationCount = 0;
        this._updateCloseGroupDecorations();
    },

    incrementCloseGroupDecorationCount: function()
    {
        ++this._closeGroupDecorationCount;
        this._updateCloseGroupDecorations();
    },

    _updateCloseGroupDecorations: function()
    {
        if (!this._nestingLevelMarkers)
            return;
        for (var i = 0, n = this._nestingLevelMarkers.length; i < n; ++i) {
            var marker = this._nestingLevelMarkers[i];
            marker.classList.toggle("group-closed", n - i <= this._closeGroupDecorationCount);
        }
    },

    /**
     * @return {!Element}
     */
    contentElement: function()
    {
        if (this._element)
            return this._element;

        var element = createElementWithClass("div", "console-message");
        this._element = element;

        if (this._message.type === WebInspector.ConsoleMessage.MessageType.StartGroup || this._message.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed)
            element.classList.add("console-group-title");

        element.appendChild(this.formattedMessage());

        if (this._repeatCount > 1)
            this._showRepeatCountElement();

        this.updateTimestamp(WebInspector.moduleSetting("consoleTimestampsEnabled").get());

        return this._element;
    },

    /**
     * @return {!Element}
     */
    toMessageElement: function()
    {
        if (this._wrapperElement)
            return this._wrapperElement;

        this._wrapperElement = createElement("div");
        this.updateMessageElement();
        return this._wrapperElement;
    },

    updateMessageElement: function()
    {
        if (!this._wrapperElement)
            return;

        this._wrapperElement.className = "console-message-wrapper";
        this._wrapperElement.removeChildren();

        this._nestingLevelMarkers = [];
        for (var i = 0; i < this._nestingLevel; ++i)
            this._nestingLevelMarkers.push(this._wrapperElement.createChild("div", "nesting-level-marker"));
        this._updateCloseGroupDecorations();
        this._wrapperElement.message = this;

        switch (this._message.level) {
        case WebInspector.ConsoleMessage.MessageLevel.Log:
            this._wrapperElement.classList.add("console-log-level");
            break;
        case WebInspector.ConsoleMessage.MessageLevel.Debug:
            this._wrapperElement.classList.add("console-debug-level");
            break;
        case WebInspector.ConsoleMessage.MessageLevel.Warning:
            this._wrapperElement.classList.add("console-warning-level");
            break;
        case WebInspector.ConsoleMessage.MessageLevel.Error:
            this._wrapperElement.classList.add("console-error-level");
            break;
        case WebInspector.ConsoleMessage.MessageLevel.RevokedError:
            this._wrapperElement.classList.add("console-revokedError-level");
            break;
        case WebInspector.ConsoleMessage.MessageLevel.Info:
            this._wrapperElement.classList.add("console-info-level");
            break;
        }

        this._wrapperElement.appendChild(this.contentElement());
    },

    /**
     * @param {!TreeElement} parentTreeElement
     */
    _populateStackTraceTreeElement: function(parentTreeElement)
    {
        var target = this._target();
        if (!target)
            return;
        var content = WebInspector.DOMPresentationUtils.buildStackTracePreviewContents(target,
            this._linkifier, this._message.stackTrace, this._message.asyncStackTrace);
        var treeElement = new TreeElement(content);
        treeElement.selectable = false;
        parentTreeElement.appendChild(treeElement);
    },

    resetIncrementRepeatCount: function()
    {
        this._repeatCount = 1;
        if (!this._repeatCountElement)
            return;

        this._repeatCountElement.remove();
        delete this._repeatCountElement;
    },

    incrementRepeatCount: function()
    {
        this._repeatCount++;
        this._showRepeatCountElement();
    },

    _showRepeatCountElement: function()
    {
        if (!this._element)
            return;

        if (!this._repeatCountElement) {
            this._repeatCountElement = createElement("span");
            this._repeatCountElement.className = "bubble-repeat-count";

            this._element.insertBefore(this._repeatCountElement, this._element.firstChild);
            this._element.classList.add("repeated-message");
        }
        this._repeatCountElement.textContent = this._repeatCount;
    },

    /**
     * @override
     * @return {string}
     */
    toString: function()
    {
        var sourceString;
        switch (this._message.source) {
            case WebInspector.ConsoleMessage.MessageSource.XML:
                sourceString = "XML";
                break;
            case WebInspector.ConsoleMessage.MessageSource.JS:
                sourceString = "JavaScript";
                break;
            case WebInspector.ConsoleMessage.MessageSource.Network:
                sourceString = "Network";
                break;
            case WebInspector.ConsoleMessage.MessageSource.ConsoleAPI:
                sourceString = "ConsoleAPI";
                break;
            case WebInspector.ConsoleMessage.MessageSource.Storage:
                sourceString = "Storage";
                break;
            case WebInspector.ConsoleMessage.MessageSource.AppCache:
                sourceString = "AppCache";
                break;
            case WebInspector.ConsoleMessage.MessageSource.Rendering:
                sourceString = "Rendering";
                break;
            case WebInspector.ConsoleMessage.MessageSource.CSS:
                sourceString = "CSS";
                break;
            case WebInspector.ConsoleMessage.MessageSource.Security:
                sourceString = "Security";
                break;
            case WebInspector.ConsoleMessage.MessageSource.Other:
                sourceString = "Other";
                break;
        }

        var typeString;
        switch (this._message.type) {
            case WebInspector.ConsoleMessage.MessageType.Log:
                typeString = "Log";
                break;
            case WebInspector.ConsoleMessage.MessageType.Dir:
                typeString = "Dir";
                break;
            case WebInspector.ConsoleMessage.MessageType.DirXML:
                typeString = "Dir XML";
                break;
            case WebInspector.ConsoleMessage.MessageType.Trace:
                typeString = "Trace";
                break;
            case WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed:
            case WebInspector.ConsoleMessage.MessageType.StartGroup:
                typeString = "Start Group";
                break;
            case WebInspector.ConsoleMessage.MessageType.EndGroup:
                typeString = "End Group";
                break;
            case WebInspector.ConsoleMessage.MessageType.Assert:
                typeString = "Assert";
                break;
            case WebInspector.ConsoleMessage.MessageType.Result:
                typeString = "Result";
                break;
            case WebInspector.ConsoleMessage.MessageType.Profile:
            case WebInspector.ConsoleMessage.MessageType.ProfileEnd:
                typeString = "Profiling";
                break;
        }

        var levelString;
        switch (this._message.level) {
            case WebInspector.ConsoleMessage.MessageLevel.Log:
                levelString = "Log";
                break;
            case WebInspector.ConsoleMessage.MessageLevel.Warning:
                levelString = "Warning";
                break;
            case WebInspector.ConsoleMessage.MessageLevel.Debug:
                levelString = "Debug";
                break;
            case WebInspector.ConsoleMessage.MessageLevel.Error:
                levelString = "Error";
                break;
            case WebInspector.ConsoleMessage.MessageLevel.RevokedError:
                levelString = "RevokedError";
                break;
            case WebInspector.ConsoleMessage.MessageLevel.Info:
                levelString = "Info";
                break;
        }

        return sourceString + " " + typeString + " " + levelString + ": " + this.formattedMessage().textContent + "\n" + this._message.url + " line " + this._message.line;
    },

    get text()
    {
        return this._message.messageText;
    },

    /**
     * @param {?RegExp} regex
     */
    setSearchRegex: function(regex)
    {
        if (this._searchHiglightNodeChanges && this._searchHiglightNodeChanges.length)
            WebInspector.revertDomChanges(this._searchHiglightNodeChanges);
        this._searchRegex = regex;
        this._searchHighlightNodes = [];
        this._searchHiglightNodeChanges = [];
        if (!this._searchRegex)
            return;

        var text = this.searchableElement().deepTextContent();
        var match;
        this._searchRegex.lastIndex = 0;
        var sourceRanges = [];
        while ((match = this._searchRegex.exec(text)) && match[0])
            sourceRanges.push(new WebInspector.SourceRange(match.index, match[0].length));

        if (sourceRanges.length && this.searchableElement())
            this._searchHighlightNodes = WebInspector.highlightSearchResults(this.searchableElement(), sourceRanges, this._searchHiglightNodeChanges);
    },

    /**
     * @return {?RegExp}
     */
    searchRegex: function()
    {
        return this._searchRegex;
    },

    /**
     * @return {number}
     */
    searchCount: function()
    {
        return this._searchHighlightNodes.length;
    },

    /**
     * @return {!Element}
     */
    searchHighlightNode: function(index)
    {
        return this._searchHighlightNodes[index];
    },

    /**
     * @return {!Element}
     */
    searchableElement: function()
    {
        this.formattedMessage();
        return this._messageElement;
    },

    /**
     * @param {string} string
     * @return {?Element}
     */
    _tryFormatAsError: function(string)
    {
        var errorPrefixes = ["EvalError", "ReferenceError", "SyntaxError", "TypeError", "RangeError", "Error", "URIError"];
        var target = this._target();
        if (!target || !errorPrefixes.some(String.prototype.startsWith.bind(new String(string))))
            return null;
        var debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
        if (!debuggerModel)
            return null;

        var lines = string.split("\n");
        var links = [];
        var position = 0;
        for (var i = 0; i < lines.length; ++i) {
            position += i > 0 ? lines[i - 1].length + 1 : 0;
            var isCallFrameLine = /^\s*at\s/.test(lines[i]);
            if (!isCallFrameLine && links.length)
                return null;

            if (!isCallFrameLine)
                continue;

            var openBracketIndex = lines[i].indexOf("(");
            var closeBracketIndex = lines[i].indexOf(")");
            var hasOpenBracket = openBracketIndex !== -1;
            var hasCloseBracket = closeBracketIndex !== -1;

            if ((openBracketIndex > closeBracketIndex) ||  (hasOpenBracket ^ hasCloseBracket))
                return null;

            var left = hasOpenBracket ? openBracketIndex + 1 : lines[i].indexOf("at") + 3;
            var right = hasOpenBracket ? closeBracketIndex : lines[i].length;
            var linkCandidate = lines[i].substring(left, right);
            var splitResult = WebInspector.ParsedURL.splitLineAndColumn(linkCandidate);
            if (!splitResult)
                return null;

            var parsed = splitResult.url.asParsedURL();
            var url;
            if (parsed)
                url = parsed.url;
            else if (debuggerModel.scriptsForSourceURL(splitResult.url).length)
                url = splitResult.url;
            else if (splitResult.url === "<anonymous>")
                continue;
            else
                return null;

            links.push({url: url, positionLeft: position + left, positionRight: position + right, lineNumber: splitResult.lineNumber, columnNumber: splitResult.columnNumber});
        }

        if (!links.length)
            return null;

        var formattedResult = createElement("span");
        var start = 0;
        for (var i = 0; i < links.length; ++i) {
            formattedResult.appendChild(WebInspector.linkifyStringAsFragment(string.substring(start, links[i].positionLeft)));
            formattedResult.appendChild(this._linkifier.linkifyScriptLocation(target, null, links[i].url, links[i].lineNumber, links[i].columnNumber));
            start = links[i].positionRight;
        }

        if (start != string.length)
            formattedResult.appendChild(WebInspector.linkifyStringAsFragment(string.substring(start)));

        return formattedResult;
    }
}

/**
 * @constructor
 * @extends {WebInspector.ConsoleViewMessage}
 * @param {!WebInspector.ConsoleMessage} consoleMessage
 * @param {!WebInspector.Linkifier} linkifier
 * @param {number} nestingLevel
 */
WebInspector.ConsoleGroupViewMessage = function(consoleMessage, linkifier, nestingLevel)
{
    console.assert(consoleMessage.isGroupStartMessage());
    WebInspector.ConsoleViewMessage.call(this, consoleMessage, linkifier, nestingLevel);
    this.setCollapsed(consoleMessage.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed);
}

WebInspector.ConsoleGroupViewMessage.prototype = {
    /**
     * @param {boolean} collapsed
     */
    setCollapsed: function(collapsed)
    {
        this._collapsed = collapsed;
        if (this._wrapperElement)
            this._wrapperElement.classList.toggle("collapsed", this._collapsed);
    },

    /**
     * @return {boolean}
     */
    collapsed: function()
    {
       return this._collapsed;
    },

    /**
     * @override
     * @return {!Element}
     */
    toMessageElement: function()
    {
        if (!this._wrapperElement) {
            WebInspector.ConsoleViewMessage.prototype.toMessageElement.call(this);
            this._wrapperElement.classList.toggle("collapsed", this._collapsed);
        }
        return this._wrapperElement;
    },

    __proto__: WebInspector.ConsoleViewMessage.prototype
}
