<!doctype html>
<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script src="../../http/tests/inspector/debugger/debugger-test.js"></script>
<script src="./resources/tail-recursion.js"></script>
<script>

function test()
{
    var scriptObject;

    function remoteObjectJSONFilter(key, value) {
        if (key === "_target" || key === "_listeners")
            return undefined;
        if (key === "_objectId" || key === "_stackTrace")
            return "<filtered>";
        return value;
    }

    function startTest() {
        InspectorTest.log("Starting Test");
        // 0 based indices.
        var testInfos = [{line : 3, column : 8}, {line : 4, column : 8}];
        for (let testInfo of testInfos) {
            let location = scriptObject.createSourceCodeLocation(testInfo.line, testInfo.column);
            let breakpoint = new WI.Breakpoint(location);
            WI.debuggerManager.addBreakpoint(breakpoint);
        }
        InspectorTest.evaluateInPage("startRecurse()");
    }

    let numBreakpointHits = 0;
    WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.CallFramesDidChange, function(event) {
        var activeCallFrame = WI.debuggerManager.activeCallFrame;

        if (!activeCallFrame)
            return;

        numBreakpointHits++;
        var stopLocation = "line: " + activeCallFrame.sourceCodeLocation.lineNumber + ", column: " + activeCallFrame.sourceCodeLocation.columnNumber;

        InspectorTest.log("\n\n------------------------------------");
        InspectorTest.log("Hit breakpoint at " + stopLocation);
        InspectorTest.log("numBreakpointHits: " + numBreakpointHits);
        const numFramesToInspect = 50;
        InspectorTest.log("Going to look at the top " + numFramesToInspect + " frames.");
        InspectorTest.log("------------------------------------");

        let targetData = WI.debuggerManager.dataForTarget(WI.debuggerManager.activeCallFrame.target);
        let callFrames = targetData.callFrames;

        InspectorTest.assert(callFrames.length > numFramesToInspect); // We just look at top 50. This isn't a precise number. But it gets at the gist of the debugging experience.
        for (let i = 0; i < numFramesToInspect; i++) {
            let callFrame = callFrames[i];
            InspectorTest.assert(callFrame.functionName === "recurse");
            let topScope = callFrame.scopeChain[0];

            if (i > 0)
                InspectorTest.assert(callFrame.isTailDeleted);
            else
                InspectorTest.assert(!callFrame.isTailDeleted);

            topScope.objects[0].getPropertyDescriptors(function(properties) {
                let found = false;
                for (let propertyDescriptor of properties) {
                    if (propertyDescriptor.name === 'i') {
                        found = true;
                        InspectorTest.log("Looking at frame number: " + i);
                        InspectorTest.log("    variable 'i': " + JSON.stringify(propertyDescriptor.value, remoteObjectJSONFilter));
                        InspectorTest.assert(propertyDescriptor.value.type === 'number');
                        if (numBreakpointHits === 2 && i === 0)
                            InspectorTest.assert(propertyDescriptor.value.value === i + 1); // this tests the i++ inside tail-recurse.js
                        else
                            InspectorTest.assert(propertyDescriptor.value.value === i);
                    }
                }
                InspectorTest.assert(found);
            });
        }

        WI.debuggerManager.resume();
    });

    WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Resumed, function(event) {
        if (numBreakpointHits === 2) {
            InspectorTest.log("Tests done");
            InspectorTest.completeTest();
        }
    });

    WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ScriptAdded, function(event) {
        eventScriptObject = event.data.script;
        
        if (/tail-recursion\.js$/.test(eventScriptObject.url)) {
            scriptObject = eventScriptObject;
            startTest();
            return;
        }

    });

    InspectorTest.reloadPage();
}
</script>
</head>
<body onload="runTest()">
    <p>Testing that we keep around tail deleted frames in the inspector. </p>
</body>
</html>
