/*
 * Copyright (C) 2013, 2014 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
 * HOLDER OR 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.
 */

WebInspector.DebuggableType = {
    Web: "web",
    JavaScript: "javascript"
};

WebInspector.loaded = function()
{
    this.debuggableType = WebInspector.DebuggableType.Web;
    this.hasExtraDomains = false;

    // Register observers for events from the InspectorBackend.
    // The initialization order should match the same in Main.js.
    InspectorBackend.registerInspectorDispatcher(new WebInspector.InspectorObserver);
    InspectorBackend.registerPageDispatcher(new WebInspector.PageObserver);
    InspectorBackend.registerDOMDispatcher(new WebInspector.DOMObserver);
    InspectorBackend.registerNetworkDispatcher(new WebInspector.NetworkObserver);
    InspectorBackend.registerDebuggerDispatcher(new WebInspector.DebuggerObserver);
    InspectorBackend.registerTimelineDispatcher(new WebInspector.TimelineObserver);
    InspectorBackend.registerCSSDispatcher(new WebInspector.CSSObserver);
    InspectorBackend.registerRuntimeDispatcher(new WebInspector.RuntimeObserver);
    if (InspectorBackend.registerReplayDispatcher)
        InspectorBackend.registerReplayDispatcher(new WebInspector.ReplayObserver);

    // Instantiate controllers used by tests.
    this.frameResourceManager = new WebInspector.FrameResourceManager;
    this.domTreeManager = new WebInspector.DOMTreeManager;
    this.cssStyleManager = new WebInspector.CSSStyleManager;
    this.runtimeManager = new WebInspector.RuntimeManager;
    this.timelineManager = new WebInspector.TimelineManager;
    this.debuggerManager = new WebInspector.DebuggerManager;
    this.probeManager = new WebInspector.ProbeManager;
    this.replayManager = new WebInspector.ReplayManager;

    // Global controllers.
    this.quickConsole = {executionContextIdentifier: undefined};

    document.addEventListener("DOMContentLoaded", this.contentLoaded.bind(this));

    // Enable agents.
    InspectorAgent.enable();

    // Perform one-time tasks.
    WebInspector.CSSCompletions.requestCSSNameCompletions();

    // Global settings.
    this.showShadowDOMSetting = new WebInspector.Setting("show-shadow-dom", true);
}

WebInspector.contentLoaded = function()
{
    // Signal that the frontend is now ready to receive messages.
    InspectorFrontendAPI.loadCompleted();

    // Tell the InspectorFrontendHost we loaded, which causes the window to display
    // and pending InspectorFrontendAPI commands to be sent.
    InspectorFrontendHost.loaded();
}

WebInspector.UIString = function(string)
{
    return string;
}

// Add stubs that are called by the frontend API.
WebInspector.updateDockedState = function()
{
}

// InspectorTest contains extra methods that are only available to test code running
// in the Web Inspector page. They rely on equivalents in the actual test page
// which are provided by `inspector-test.js`.
InspectorTest = {};

// This is useful for debugging Inspector tests by synchronously logging messages.
InspectorTest.dumpMessagesToConsole = false;

// This is a workaround for the fact that it would be hard to set up a constructor,
// prototype, and prototype chain for the singleton InspectorTest.
InspectorTest.EventDispatcher = function()
{
    // FIXME: Convert this to a WebInspector.Object subclass, and call super().
    // WebInspector.Object.call(this);
};

InspectorTest.EventDispatcher.Event = {
    TestPageDidLoad: "inspector-test-test-page-did-load"
};

InspectorTest.EventDispatcher.prototype = {
    __proto__: WebInspector.Object.prototype,
    constructor: InspectorTest.EventDispatcher,

    dispatchEvent: function(event)
    {
        this.dispatchEventToListeners(event);
    }
};

InspectorTest.eventDispatcher = new InspectorTest.EventDispatcher;

// Note: Additional InspectorTest methods are included on a per-test basis from
// files like `debugger-test.js`.

// Appends a log message in the test document.
InspectorTest.log = function(message)
{
    var stringifiedMessage = typeof message !== "object" ? message : JSON.stringify(message);
    InspectorTest.addResult(stringifiedMessage);
}

// Appends a message in the test document only if the condition is false.
InspectorTest.assert = function(condition, message)
{
    if (condition)
        return;

    var stringifiedMessage = typeof message !== "object" ? message : JSON.stringify(message);
    InspectorTest.addResult("ASSERT: " + stringifiedMessage);
}

// Appends a message in the test document whether the condition is true or not.
InspectorTest.expectThat = function(condition, message)
{
    var prefix = condition ? "PASS" : "FAIL";
    var stringifiedMessage = typeof message !== "object" ? message : JSON.stringify(message);
    InspectorTest.addResult(prefix + ": " + stringifiedMessage);
}

// This function should only be used to debug tests and not to produce normal test output.
InspectorTest.debugLog = function(message)
{
    if (InspectorTest.dumpMessagesToConsole)
        InspectorFrontendHost.unbufferedLog("debugLog: " + message);

    this.evaluateInPage("InspectorTestProxy.debugLog(unescape('" + escape(JSON.stringify(message)) + "'))");
}

InspectorTest.completeTest = function()
{
    if (InspectorTest.dumpMessagesToConsole)
        InspectorFrontendHost.unbufferedLog("InspectorTest.completeTest()");

    function signalCompletionToTestPage() {
        InspectorBackend.runAfterPendingDispatches(this.evaluateInPage.bind(this, "InspectorTestProxy.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._shouldResendResults)
        this._resendResults(signalCompletionToTestPage.bind(this));
    else
        signalCompletionToTestPage.call(this);
}

InspectorTest.evaluateInPage = function(codeString, callback)
{
    // 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 (!RuntimeAgent) {
        this._originalConsoleMethods["error"]("Tried to evaluate in test page, but connection not yet established:", codeString);
        return;
    }

    RuntimeAgent.evaluate.invoke({expression: codeString, objectGroup: "test", includeCommandLineAPI: false}, callback);
}

InspectorTest.addResult = function(text)
{
    this._results.push(text);

    if (InspectorTest.dumpMessagesToConsole)
        InspectorFrontendHost.unbufferedLog("addResult: " + text);

    if (!this._testPageIsReloading)
        this.evaluateInPage("InspectorTestProxy.addResult(unescape('" + escape(text) + "'))");
}

InspectorTest._resendResults = function(callback)
{
    console.assert(this._shouldResendResults);
    delete this._shouldResendResults;

    var pendingResponseCount = 1 + this._results.length;
    function decrementPendingResponseCount() {
        pendingResponseCount--;
        if (!pendingResponseCount && typeof callback === "function")
            callback();
    }

    this.evaluateInPage("InspectorTestProxy.clearResults()", decrementPendingResponseCount);
    for (var result of this._results)
        this.evaluateInPage("InspectorTestProxy.addResult(unescape('" + escape(result) + "'))", decrementPendingResponseCount);
}

InspectorTest.testPageDidLoad = function()
{
    this._testPageIsReloading = false;
    this._resendResults();

    this.eventDispatcher.dispatchEvent(InspectorTest.EventDispatcher.Event.TestPageDidLoad);
}

InspectorTest.reloadPage = function(shouldIgnoreCache)
{
    return PageAgent.reload.promise(!!shouldIgnoreCache)
        .then(function() {
            this._shouldResendResults = true;
            this._testPageIsReloading = true;

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

InspectorTest.reportUncaughtException = function(message, url, lineNumber)
{
    var result = "Uncaught exception in inspector page: " + message + " [" + url + ":" + lineNumber + "]";

    // 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 (!InspectorFrontendHost || !InspectorBackend) {
        this._originalConsoleMethods["error"](result);
        return false;
    }

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

// Initialize reporting mechanisms before loading the rest of the inspector page.
InspectorTest._results = [];
InspectorTest._shouldResendResults = true;
InspectorTest._originalConsoleMethods = {};

// Catch syntax errors, type errors, and other exceptions.
window.onerror = InspectorTest.reportUncaughtException.bind(InspectorTest);

for (var logType of ["log", "error", "info"]) {
    // Redirect console methods to log messages into the test page's DOM.
    InspectorTest._originalConsoleMethods[logType] = console[logType].bind(console);
    console[logType] = function() {
        InspectorTest.addResult(logType.toUpperCase() + ": " + Array.from(arguments).toString());
    };
}
