/*
 * Copyright (C) 2017 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.WebSocketDataGridNode = class WebSocketDataGridNode extends WI.DataGridNode
{
    // Public

    createCellContent(columnIdentifier)
    {
        if (columnIdentifier === "data") {
            let fragment = document.createDocumentFragment();
            if (this._data.isOutgoing) {
                let iconElement = WI.ImageUtilities.useSVGSymbol("Images/ArrowUp.svg", "icon", WI.UIString("Outgoing message"));
                fragment.appendChild(iconElement);
            }
            fragment.appendChild(document.createTextNode(this._data.data));
            return fragment;
        }

        if (columnIdentifier === "time")
            return this._timeStringFromTimestamp(this._data.time);

        return super.createCellContent(columnIdentifier);
    }

    // Protected

    appendContextMenuItems(contextMenu)
    {
        let logResult = (result, wasThrown, savedResultIndex) => {
            console.assert(!wasThrown);

            const title = WI.UIString("Selected Frame");
            const addSpecialUserLogClass = true;
            const shouldRevealConsole = true;
            WI.consoleLogViewController.appendImmediateExecutionWithResult(title, result, addSpecialUserLogClass, shouldRevealConsole);
        };

        if (this._data.isText) {
            let remoteObject = WI.RemoteObject.fromPrimitiveValue(this._data.data);
            contextMenu.appendItem(WI.UIString("Log Frame Text"), () => {
                WI.runtimeManager.saveResult(remoteObject, (savedResultIndex) => {
                    logResult(remoteObject, false, savedResultIndex);
                });
            });

            try {
                // The result of this is unnecessary, as we just need the string to evaluate.
                // We still need to execute this, however, in order to try-catch if it fails.
                JSON.parse(this._data.data);

                contextMenu.appendItem(WI.UIString("Log Frame Value"), () => {
                    const options = {
                        objectGroup: WI.RuntimeManager.ConsoleObjectGroup,
                        generatePreview: true,
                        saveResult: true,
                        doNotPauseOnExceptionsAndMuteConsole: true,
                    };

                    let expression = "(" + this._data.data + ")";
                    WI.runtimeManager.evaluateInInspectedWindow(expression, options, logResult);
                });
            } catch { }

            contextMenu.appendSeparator();
        }

        return super.appendContextMenuItems(contextMenu);
    }

    // Private

    _timeStringFromTimestamp(timestamp)
    {
        return new Date(timestamp * 1000).toLocaleTimeString();
    }
};
