/*
 * Copyright (C) 2013-2016 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.
 */

FrontendTestHarness = class FrontendTestHarness extends TestHarness
{
    constructor()
    {
        super();

        this._results = [];
        this._shouldResendResults = true;

        // Options that are set per-test for debugging purposes.
        this.dumpActivityToSystemConsole = false;
    }

    // TestHarness Overrides

    completeTest()
    {
        if (this.dumpActivityToSystemConsole)
            InspectorFrontendHost.unbufferedLog("completeTest()");

        // Wait for results to be resent before requesting completeTest(). Otherwise, messages will be
        // queued after pending dispatches run to zero and the test page will quit before processing them.
        if (this._testPageIsReloading) {
            this._completeTestAfterReload = true;
            return;
        }

        InspectorBackend.runAfterPendingDispatches(this.evaluateInPage.bind(this, "TestPage.completeTest()"));
    }

    addResult(message)
    {
        let stringifiedMessage = TestHarness.messageAsString(message);

        // Save the stringified message, since message may be a DOM element that won't survive reload.
        this._results.push(stringifiedMessage);

        if (this.dumpActivityToSystemConsole)
            InspectorFrontendHost.unbufferedLog(stringifiedMessage);

        if (!this._testPageIsReloading)
            this.evaluateInPage(`TestPage.addResult(unescape("${escape(stringifiedMessage)}"))`);
    }

    debugLog(message)
    {
        let stringifiedMessage = TestHarness.messageAsString(message);

        if (this.dumpActivityToSystemConsole)
            InspectorFrontendHost.unbufferedLog(stringifiedMessage);

        this.evaluateInPage(`TestPage.debugLog(unescape("${escape(stringifiedMessage)}"));`);
    }

    evaluateInPage(expression, callback, options = {})
    {
        let remoteObjectOnly = !!options.remoteObjectOnly;
        let target = WI.assumingMainTarget();

        // If we load this page outside of the inspector, or hit an early error when loading
        // the test frontend, then defer evaluating the commands (indefinitely in the former case).
        if (this._originalConsole && (!target || !target.hasDomain("Runtime"))) {
            this._originalConsole["error"]("Tried to evaluate in test page, but connection not yet established:", expression);
            return;
        }

        // Return primitive values directly, otherwise return a WI.RemoteObject instance.
        function translateResult(result) {
            let remoteObject = WI.RemoteObject.fromPayload(result);
            return (!remoteObjectOnly && remoteObject.hasValue()) ? remoteObject.value : remoteObject;
        }

        let response = target.RuntimeAgent.evaluate.invoke({expression, objectGroup: "test", includeCommandLineAPI: false});
        if (callback && typeof callback === "function") {
            response = response.then(({result, wasThrown}) => callback(null, translateResult(result), wasThrown));
            response = response.catch((error) => callback(error, null, false));
        } else {
            // Turn a thrown Error result into a promise rejection.
            return response.then(({result, wasThrown}) => {
                result = translateResult(result);
                if (result && wasThrown)
                    return Promise.reject(new Error(result.description));
                return Promise.resolve(result);
            });
        }
    }

    debug()
    {
        this.dumpActivityToSystemConsole = true;
        InspectorBackend.dumpInspectorProtocolMessages = true;
    }

    // Frontend test-specific methods.

    expectNoError(error)
    {
        if (error) {
            InspectorTest.log("PROTOCOL ERROR: " + error);
            InspectorTest.completeTest();
            throw "PROTOCOL ERROR";
        }
    }

    testPageDidLoad()
    {
        if (this.dumpActivityToSystemConsole)
            InspectorFrontendHost.unbufferedLog("testPageDidLoad()");

        this._testPageIsReloading = false;
        this._resendResults();

        this.dispatchEventToListeners(FrontendTestHarness.Event.TestPageDidLoad);

        if (this._completeTestAfterReload)
            this.completeTest();
    }

    reloadPage(options = {})
    {
        console.assert(!this._testPageIsReloading);
        console.assert(!this._testPageReloadedOnce);

        this._testPageIsReloading = true;

        let {ignoreCache, revalidateAllResources} = options;
        ignoreCache = !!ignoreCache;
        revalidateAllResources = !!revalidateAllResources;

        let target = WI.assumingMainTarget();
        return target.PageAgent.reload.invoke({ignoreCache, revalidateAllResources})
            .then(() => {
                this._shouldResendResults = true;
                this._testPageReloadedOnce = true;

                return Promise.resolve(null);
            });
    }

    redirectRequestAnimationFrame()
    {
        console.assert(!this._originalRequestAnimationFrame);
        if (this._originalRequestAnimationFrame)
            return;

        this._originalRequestAnimationFrame = window.requestAnimationFrame;
        this._requestAnimationFrameCallbacks = new Map;
        this._nextRequestIdentifier = 1;

        window.requestAnimationFrame = (callback) => {
            let requestIdentifier = this._nextRequestIdentifier++;
            this._requestAnimationFrameCallbacks.set(requestIdentifier, callback);
            if (this._requestAnimationFrameTimer)
                return requestIdentifier;

            let dispatchCallbacks = () => {
                let callbacks = this._requestAnimationFrameCallbacks;
                this._requestAnimationFrameCallbacks = new Map;
                this._requestAnimationFrameTimer = undefined;
                let timestamp = window.performance.now();
                for (let callback of callbacks.values())
                    callback(timestamp);
            };

            this._requestAnimationFrameTimer = setTimeout(dispatchCallbacks, 0);
            return requestIdentifier;
        };

        window.cancelAnimationFrame = (requestIdentifier) => {
            if (!this._requestAnimationFrameCallbacks.delete(requestIdentifier))
                return;

            if (!this._requestAnimationFrameCallbacks.size) {
                clearTimeout(this._requestAnimationFrameTimer);
                this._requestAnimationFrameTimer = undefined;
            }
        };
    }

    redirectConsoleToTestOutput()
    {
        // We can't use arrow functions here because of 'arguments'. It might
        // be okay once rest parameters work.
        let self = this;
        function createProxyConsoleHandler(type) {
            return function() {
                self.addResult(`${type}: ` + Array.from(arguments).join(" "));
            };
        }

        function createProxyConsoleTraceHandler(){
            return function() {
                try {
                    throw new Exception();
                } catch (e) {
                    // Skip the first frame which is added by this function.
                    let frames = e.stack.split("\n").slice(1);
                    let sanitizedFrames = frames.map(TestHarness.sanitizeStackFrame);
                    self.addResult("TRACE: " + Array.from(arguments).join(" "));
                    self.addResult(sanitizedFrames.join("\n"));
                }
            };
        }

        let redirectedMethods = {};
        for (let key in window.console)
            redirectedMethods[key] = window.console[key];

        for (let type of ["log", "error", "info", "warn"])
            redirectedMethods[type] = createProxyConsoleHandler(type.toUpperCase());

        redirectedMethods["trace"] = createProxyConsoleTraceHandler();

        this._originalConsole = window.console;
        window.console = redirectedMethods;
    }

    reportUnhandledRejection(error)
    {
        let message = error.message;
        let stack = error.stack;
        let result = `Unhandled promise rejection in inspector page: ${message}\n`;
        if (stack) {
            let sanitizedStack = this.sanitizeStack(stack);
            result += `\nStack Trace: ${sanitizedStack}\n`;
        }

        // If the connection to the test page is not set up, then just dump to console and give up.
        // Errors encountered this early can be debugged by loading Test.html in a normal browser page.
        if (this._originalConsole && !this._testPageHasLoaded())
            this._originalConsole["error"](result);

        this.addResult(result);
        this.completeTest();

        // Stop default handler so we can empty InspectorBackend's message queue.
        return true;
    }

    reportUncaughtExceptionFromEvent(message, url, lineNumber, columnNumber)
    {
        // An exception thrown from a timer callback does not report a URL.
        if (url === "undefined")
            url = "global";

        return this.reportUncaughtException({message, url, lineNumber, columnNumber});
    }

    reportUncaughtException({message, url, lineNumber, columnNumber, stack, code})
    {
        let result;
        let sanitizedURL = TestHarness.sanitizeURL(url);
        let sanitizedStack = this.sanitizeStack(stack);
        if (url || lineNumber || columnNumber)
            result = `Uncaught exception in Inspector page: ${message} [${sanitizedURL}:${lineNumber}:${columnNumber}]\n`;
        else
            result = `Uncaught exception in Inspector page: ${message}\n`;

        if (stack)
            result += `\nStack Trace:\n${sanitizedStack}\n`;
        if (code)
            result += `\nEvaluated Code:\n${code}`;

        // If the connection to the test page is not set up, then just dump to console and give up.
        // Errors encountered this early can be debugged by loading Test.html in a normal browser page.
        if (this._originalConsole && !this._testPageHasLoaded())
            this._originalConsole["error"](result);

        this.addResult(result);
        this.completeTest();
        // Stop default handler so we can empty InspectorBackend's message queue.
        return true;
    }

    // Private

    _testPageHasLoaded()
    {
        return self._shouldResendResults;
    }

    _resendResults()
    {
        console.assert(this._shouldResendResults);
        this._shouldResendResults = false;

        if (this.dumpActivityToSystemConsole)
            InspectorFrontendHost.unbufferedLog("_resendResults()");

        for (let result of this._results)
            this.evaluateInPage(`TestPage.addResult(unescape("${escape(result)}"))`);
    }
};

FrontendTestHarness.Event = {
    TestPageDidLoad: "frontend-test-test-page-did-load"
};
