/*
 * Copyright (C) 2012 Samsung Electronics. All rights reserved.
 * Copyright (C) 2014, 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 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.
 */

InspectorProtocol = {};
InspectorProtocol._dispatchTable = [];
InspectorProtocol._placeholderRequestIds = [];
InspectorProtocol._requestId = -1;
InspectorProtocol.eventHandler = {};

InspectorProtocol.sendCommand = function(methodOrObject, params, handler)
{
    // Allow new-style arguments object, as in awaitCommand.
    let method = methodOrObject;
    if (typeof methodOrObject === "object")
        ({method, params, handler} = methodOrObject);
    else if (!params)
        params = {};

    this._dispatchTable[++this._requestId] = handler;
    let messageObject = {method, params, id: this._requestId};
    this._sendMessage(messageObject);

    return this._requestId;
};

InspectorProtocol.awaitCommand = function(args)
{
    let {method, params} = args;
    let messageObject = {method, params, id: ++this._requestId};

    return this.awaitMessage(messageObject);
};

InspectorProtocol.awaitMessage = function(messageObject)
{
    // Send a raw message to the backend. Mostly used to test the backend's error handling.
    return new Promise((resolve, reject) => {
        let requestId = messageObject.id;

        // If the caller did not provide an id, then make one up so that the response
        // can be used to settle a promise.
        if (typeof requestId !== "number") {
            requestId = ++this._requestId;
            this._placeholderRequestIds.push(requestId);
        }

        this._dispatchTable[requestId] = {resolve, reject};
        this._sendMessage(messageObject);
    });
};

InspectorProtocol.awaitEvent = function(args)
{
    let event = args.event;
    if (typeof event !== "string")
        throw new Error("Event must be a string.");

    return new Promise((resolve, reject) => {
        InspectorProtocol.eventHandler[event] = function(message) {
            InspectorProtocol.eventHandler[event] = undefined;
            resolve(message);
        };
    });
};

InspectorProtocol._sendMessage = function(messageObject)
{
    let messageString = typeof messageObject !== "string" ? JSON.stringify(messageObject) : messageObject;

    if (ProtocolTest.dumpInspectorProtocolMessages)
        InspectorFrontendHost.unbufferedLog(`frontend: ${messageString}`);

    InspectorFrontendHost.sendMessageToBackend(messageString);
};

InspectorProtocol.addEventListener = function(eventTypeOrObject, listener)
{
    let event = eventTypeOrObject;
    if (typeof eventTypeOrObject === "object")
        ({event, listener} = eventTypeOrObject);

    if (typeof event !== "string")
        throw new Error("Event name must be a string.");

    if (typeof listener !== "function")
        throw new Error("Event listener must be callable.");

    // Convert to an array of listeners.
    let listeners = InspectorProtocol.eventHandler[event];
    if (!listeners)
        listeners = InspectorProtocol.eventHandler[event] = [];
    else if (typeof listeners === "function")
        listeners = InspectorProtocol.eventHandler[event] = [listeners];

    // Prevent registering multiple times.
    if (listeners.includes(listener))
        throw new Error("Cannot register the same listener more than once.");

    listeners.push(listener);
};

InspectorProtocol.checkForError = function(responseObject)
{
    if (responseObject.error) {
        ProtocolTest.log("PROTOCOL ERROR: " + JSON.stringify(responseObject.error));
        ProtocolTest.completeTest();
        throw "PROTOCOL ERROR";
    }
};

InspectorProtocol.dispatchMessageFromBackend = function(messageObject)
{
    // This matches the debug dumping in InspectorBackend, which is bypassed
    // by InspectorProtocol. Return messages should be dumped by InspectorBackend.
    if (ProtocolTest.dumpInspectorProtocolMessages)
        InspectorFrontendHost.unbufferedLog("backend: " + JSON.stringify(messageObject));

    // If the message has an id, then it is a reply to a command.
    let messageId = messageObject.id;

    // If the id is 'null', then it may be an error response.
    if (messageId === null)
        messageId = InspectorProtocol._placeholderRequestIds.shift();

    // If we could figure out a requestId, then dispatch the message.
    if (typeof messageId === "number") {
        let handler = InspectorProtocol._dispatchTable[messageId];
        if (!handler)
            return;

        if (typeof handler === "function")
            handler(messageObject);
        else if (typeof handler === "object") {
            let {resolve, reject} = handler;
            if ("error" in messageObject)
                reject(messageObject.error);
            else
                resolve(messageObject.result);
        }
    } else {
        // Otherwise, it is an event.
        let eventName = messageObject["method"];
        let handler = InspectorProtocol.eventHandler[eventName];
        if (!handler)
            return;

        if (typeof handler === "function")
            handler(messageObject);
        else if (handler instanceof Array) {
            handler.map((listener) => { listener.call(null, messageObject); });
        } else if (typeof handler === "object") {
            let {resolve, reject} = handler;
            if ("error" in messageObject)
                reject(messageObject.error);
            else
                resolve(messageObject.result);
        }
    }
};
