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

(function() {

const windowEvents = ["beforecopy", "copy", "click", "dragover", "focus"];
const documentEvents = ["focus", "blur", "resize", "keydown", "keyup", "mousemove", "pagehide", "contextmenu"];

function stopEventPropagation(event) {
    if (event.target.classList && event.target.classList.contains("bypass-event-blocking"))
        return;

    event.stopPropagation();
}

function blockEventHandlers() {
    // FIXME (151959): text selection on the sheet doesn't work for some reason.
    for (let name of windowEvents)
        window.addEventListener(name, stopEventPropagation, true);
    for (let name of documentEvents)
        document.addEventListener(name, stopEventPropagation, true);
}

function unblockEventHandlers() {
    for (let name of windowEvents)
        window.removeEventListener(name, stopEventPropagation, true);
    for (let name of documentEvents)
        document.removeEventListener(name, stopEventPropagation, true);
}

function urlLastPathComponent(url) {
    if (!url)
        return "";

    let slashIndex = url.lastIndexOf("/");
    if (slashIndex === -1)
        return url;

    return url.slice(slashIndex + 1);
}

function handleError(error) {
    handleUncaughtExceptionRecord({
        message: error.message,
        url: urlLastPathComponent(error.sourceURL),
        lineNumber: error.line,
        columnNumber: error.column,
        stack: error.stack,
        details: error.details,
    });
}

function handleUncaughtException(event) {
    handleUncaughtExceptionRecord({
        message: event.message,
        url: urlLastPathComponent(event.filename),
        lineNumber: event.lineno,
        columnNumber: event.colno,
        stack: typeof event.error === "object" && event.error !== null ? event.error.stack : null,
    });
}

function handleUnhandledPromiseRejection(event) {
    handleUncaughtExceptionRecord({
        message: event.reason.message,
        url: urlLastPathComponent(event.reason.sourceURL),
        lineNumber: event.reason.line,
        columnNumber: event.reason.column,
        stack: event.reason.stack,
    });
}

function handleUncaughtExceptionRecord(exceptionRecord) {
    try {
        if (WI.isDebugUIEnabled() && !WI.settings.debugEnableUncaughtExceptionReporter.value)
            return;
    } catch { }

    if (!window.__uncaughtExceptions)
        window.__uncaughtExceptions = [];

    const loadCompleted = window.__frontendCompletedLoad;
    const isFirstException = !window.__uncaughtExceptions.length;

    // If an uncaught exception happens after loading is done, only show
    // the first such exception. Many others may follow if internal
    // state has been corrupted, but these are unhelpful to report.
    if (!loadCompleted || isFirstException)
        window.__uncaughtExceptions.push(exceptionRecord);

    // If WI.contentLoaded throws an uncaught exception, then these
    // listeners will not work correctly because the UI is not fully loaded.
    // Prevent any event handlers from running in an inconsistent state.
    if (isFirstException)
        blockEventHandlers();

    if (isFirstException && !loadCompleted) {
        // Signal that loading is done even though we can't guarantee that
        // evaluating code on the inspector page will do anything useful.
        // Without this, the frontend host may never show the window.
        if (window.InspectorFrontendHost)
            InspectorFrontendHost.loaded();

        // Don't tell InspectorFrontendAPI that loading is done, since it can
        // clear some of the error boilerplate page by accident.
    }

    createErrorSheet();
}

function dismissErrorSheet() {
    unblockEventHandlers();

    window.__sheetElement.remove();
    window.__sheetElement = null;
    window.__uncaughtExceptions = [];

    // Do this last in case WebInspector's internal state is corrupted.
    try {
        WI.updateWindowTitle();
    } catch { }

    // FIXME (151959): tell the frontend host to hide a draggable title bar.
}

function createErrorSheet() {
    // Early errors like parse errors may happen in the <head>, so attach
    // a body if none exists yet. Code below expects document.body to exist.
    if (!document.body)
        document.write("<body></body></html>");

    // FIXME (151959): tell the frontend host to show a draggable title bar.
    if (window.InspectorFrontendHost)
        InspectorFrontendHost.inspectedURLChanged("Internal Error");

    // Only allow one sheet element at a time.
    if (window.__sheetElement) {
        window.__sheetElement.remove();
        window.__sheetElement = null;
    }

    const loadCompleted = window.__frontendCompletedLoad;
    let firstException = window.__uncaughtExceptions[0];

    // Inlined from Utilities.js, because that file may not have loaded.
    function insertWordBreakCharacters(text) {
        return text.replace(/([\/;:\)\]\}&?])/g, "$1\u200b");
    }

    // This trampoline is necessary since none of our functions will be
    // in scope of an href="javascript:"-style evaluation.
    function handleLinkClick(event) {
        if (event.target.tagName !== "A")
            return;
        if (event.target.id === "dismiss-error-sheet")
            dismissErrorSheet();
    }

    function formattedEntry(entry) {
        const indent = "    ";
        let lines = [`${entry.message} (at ${entry.url}:${entry.lineNumber}:${entry.columnNumber})`];
        if (entry.stack) {
            let stackLines = entry.stack.split(/\n/g);
            for (let stackLine of stackLines) {
                let atIndex = stackLine.indexOf("@");
                let slashIndex = Math.max(stackLine.lastIndexOf("/"), atIndex);
                let functionName = stackLine.substring(0, atIndex) || "?";
                let location = stackLine.substring(slashIndex + 1, stackLine.length);
                lines.push(`${indent}${functionName} @ ${location}`);
            }
        }

        if (entry.details) {
            lines.push("");
            lines.push("Additional Details:");
            for (let key in entry.details) {
                let value = entry.details[key];
                lines.push(`${indent}${key} --> ${value}`);
            }
        }

        return lines.join("\n");
    }

    let inspectedPageURL = null;
    try {
        inspectedPageURL = WI.networkManager.mainFrame.url;
    } catch { }

    let topLevelItems = [
        `Inspected URL:        ${inspectedPageURL || "(unknown)"}`,
        `Loading completed:    ${!!loadCompleted}`,
        `Frontend User Agent:  ${window.navigator.userAgent}`,
    ];

    function stringifyAndTruncateObject(object) {
        let string = JSON.stringify(object);
        return string.length > 500 ? string.substr(0, 500) + ellipsis : string;
    }

    if (window.InspectorBackend && InspectorBackend.currentDispatchState) {
        let state = InspectorBackend.currentDispatchState;
        if (state.event) {
            topLevelItems.push("Dispatch Source:      Protocol Event");
            topLevelItems.push("");
            topLevelItems.push("Protocol Event:");
            topLevelItems.push(stringifyAndTruncateObject(state.event));
        }
        if (state.response) {
            topLevelItems.push("Dispatch Source:      Protocol Command Response");
            topLevelItems.push("");
            topLevelItems.push("Protocol Command Response:");
            topLevelItems.push(stringifyAndTruncateObject(state.response));
        }
        if (state.request) {
            topLevelItems.push("");
            topLevelItems.push("Protocol Command Request:");
            topLevelItems.push(stringifyAndTruncateObject(state.request));
        }
    }

    let formattedErrorDetails = window.__uncaughtExceptions.map((entry) => formattedEntry(entry));
    let detailsForBugReport = formattedErrorDetails.map((line) => ` - ${line}`).join("\n");

    let encodedBugDescription = encodeURIComponent(`Uncaught Exception in Web Inspector.

Steps to Reproduce:
1. What were you doing? Include setup or other preparations to reproduce the exception.
2. Include explicit, accurate, and minimal steps taken. Do not include extraneous or irrelevant steps.
3. What did you expect to have happen? What actually happened?

Uncaught Exceptions:
-----------------------
${detailsForBugReport}
-----------------------

Notes:
${topLevelItems.join("\n")}
`);

    let encodedBugTitle = encodeURIComponent(`Uncaught Exception: ${firstException.message}`);
    let encodedInspectedURL = encodeURIComponent(inspectedPageURL || "http://");
    let prefilledBugReportLink = `https://bugs.webkit.org/enter_bug.cgi?alias=&assigned_to=webkit-unassigned%40lists.webkit.org&attach_text=&blocked=&bug_file_loc=${encodedInspectedURL}&bug_severity=Normal&bug_status=NEW&comment=${encodedBugDescription}&component=Web%20Inspector&contenttypeentry=&contenttypemethod=autodetect&contenttypeselection=text%2Fplain&data=&dependson=&description=&flag_type-1=X&flag_type-3=X&form_name=enter_bug&keywords=&op_sys=All&priority=P2&product=WebKit&rep_platform=All&short_desc=${encodedBugTitle}`;
    let detailsForHTML = formattedErrorDetails.map((line) => `<li>${insertWordBreakCharacters(line)}</li>`).join("\n");

    let dismissOptionHTML = !loadCompleted ? "" : `<dt>A frivolous exception will not stop me!</dt>
        <dd><a class="bypass-event-blocking" id="dismiss-error-sheet">Click to close this view</a> and return
        to the Web Inspector without reloading. However, some things might not work without reloading if the error corrupted the Inspector's internal state.</dd>`;

    let sheetElement = window.__sheetElement = document.createElement("div");
    sheetElement.classList.add("sheet-container");
    sheetElement.innerHTML = `<div class="uncaught-exception-sheet">
    <h1>
    <img src="Images/Errors.svg">
    Web Inspector encountered an internal error.
    </h1>
    <dl>
        <dd>Usually, this is caused by a syntax error while modifying the Web Inspector
        UI, or running an updated frontend with out-of-date WebKit build.</dt>
        <dt>I didn't do anything...?</dt>
        <dd><a href="${prefilledBugReportLink}" id="uncaught-exception-bug-report-link" class="bypass-event-blocking">Click to file a bug</a> as this is likely a Web Inspector bug.</dd>
        <dt>Oops, can I try again?</dt>
        <dd><a href="javascript:InspectorFrontendHost.reopen()" class="bypass-event-blocking">Click to reload the Inspector</a>
        again after making local changes.</dd>
        ${dismissOptionHTML}
    </dl>
    <h2>
    <img src="Images/Console.svg">
    These uncaught exceptions caused the problem:
    </h2>
    <p><ul>${detailsForHTML}</ul></p>
    </div>`;

    sheetElement.addEventListener("click", handleLinkClick, true);
    document.body.appendChild(sheetElement);

    document.getElementById("uncaught-exception-bug-report-link").addEventListener("click", (event) => {
        InspectorFrontendHost.openInNewTab(prefilledBugReportLink);
        event.stopImmediatePropagation();
        event.preventDefault();
    });
}

window.addEventListener("error", handleUncaughtException);
window.addEventListener("unhandledrejection", handleUnhandledPromiseRejection);
window.handleInternalException = handleError;

})();
