<html>
<head>
<script src="../../http/tests/inspector/resources/protocol-test.js"></script>
<script src="resources/exception.js"></script>
<script>
function test()
{
    var expectPause = true;

    var statementsWithoutExceptions = [
        "1+1;",
        "noException();",
        "catchNested(noException, 7);"
    ];

    var currentCaughtExceptionStatement = 0;
    var statementsWithCaughtExceptions = [
        "try{ ({}).a.b.c.d } catch (e) { console.log(`caught inline: ${stringifyError(e)}`); }",
        "catchNested(exceptionBasic, 1);",
        "catchNested(exceptionDOM, 2);",
        "catchNested(exceptionInHostFunction, 3);",
        "catchNested(throwString, 10);",
        "catchNested(throwParam, 5, new Error('error message'));"
    ];

    var currentUncaughtExceptionStatement = 0;
    var statementsWithUncaughtExceptions = [
        "({}).a.b.c.d;",
        "exceptionBasic();",
        "exceptionDOM();",
        "exceptionInHostFunction();",
        "throwString();",
        "throwParam({x:1});",
        "throwParam(new Error('error message'));"
    ];

    var extraCaughtExceptionPauses = 0;
    var extraUncaughtExceptionPauses = 0;

    function evaluateStatements(list, callback)
    {
        for (var i = 0; i < list.length; ++i) {
            var statement = list[i];
            var last = i === list.length - 1;
            var responseCallback = last ? function() { setTimeout(callback, 10); } : function(){};
            InspectorProtocol.sendCommand("Runtime.evaluate", {expression: "setTimeout(function() { " + statement + " }, 0);"}, responseCallback);
        }
    }

    function evaluateExpectedNoPauses(callback)
    {
        var statements = statementsWithoutExceptions;
        evaluateStatements(statements, function() {
            ProtocolTest.log("PASS - did not pause on non-exception statements");
            callback();
        });
    }


    var triggerNext = triggerNextCaughtException;

    function triggerNextCaughtException()
    {
        // Evaluate statement and expect to pause.
        if (currentCaughtExceptionStatement < statementsWithCaughtExceptions.length) {
            var statement = statementsWithCaughtExceptions[currentCaughtExceptionStatement++];
            InspectorProtocol.sendCommand("Runtime.evaluate", {expression: "setTimeout(function() { " + statement + " }, 0);"});
            return;
        }

        // FIXME: <https://webkit.org/b/121108> Web Inspector gets paused twice when there is an exception in host function
        if (extraCaughtExceptionPauses-- > 0)
            return;

        // Done evaluating caught exceptions statements. Move on to uncaught exceptions.
        ProtocolTest.log("PASS - paused for each caught exception");
        triggerNext = triggerNextUncaughtException;
        triggerNext();
    }

    function triggerNextUncaughtException()
    {
        // Evaluate statement and expect to pause.
        if (currentUncaughtExceptionStatement < statementsWithUncaughtExceptions.length) {
            var statement = statementsWithUncaughtExceptions[currentUncaughtExceptionStatement++];
            InspectorProtocol.sendCommand("Runtime.evaluate", {expression: "setTimeout(function() { " + statement + " }, 0);"});
            return;
        }

        // FIXME: <https://webkit.org/b/121108> Web Inspector gets paused twice when there is an exception in host function
        if (extraUncaughtExceptionPauses-- > 0)
            return;

        // Done evaluating statements to pause. Evaluate some more we do not expect to pause.
        ProtocolTest.log("PASS - paused for each uncaught exception");
        expectPause = false;
        evaluateExpectedNoPauses(function() {
            ProtocolTest.completeTest();
        });
    }


    InspectorProtocol.sendCommand("Debugger.enable", {});
    InspectorProtocol.sendCommand("Debugger.setBreakpointsActive", {active: true});
    InspectorProtocol.sendCommand("Debugger.setPauseOnExceptions", {state: "all"}, function(responseObject) {
        InspectorProtocol.checkForError(responseObject);
        ProtocolTest.log("Debugger.setPauseOnExceptions - all");
        evaluateExpectedNoPauses(function() {
            expectPause = true;
            triggerNext();
        });
    });

    InspectorProtocol.eventHandler["Debugger.paused"] = function(messageObject)
    {
        ProtocolTest.log("Paused!");

        if (!expectPause) {
            ProtocolTest.log("FAIL - debugger paused when we did not expect to");
            ProtocolTest.completeTest();
            return;
        }

        InspectorProtocol.sendCommand("Debugger.resume", {});
    }

    InspectorProtocol.eventHandler["Debugger.resumed"] = function(messageObject)
    {
        ProtocolTest.log("Resumed");
        triggerNext();
    }
}
</script>
</head>
<body onload="runTest()">
<p>Debugger.setPauseOnExceptions all</p>
</body>
</html>
