<!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-deleted-frames-this-value.js"></script>
<script>

function test()
{
    var scriptObject;

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

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

        if (!activeCallFrame)
            return;

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

        InspectorTest.log("\n\n------------------------------------");
        InspectorTest.log("Hit breakpoint at " + stopLocation);
        InspectorTest.log("------------------------------------");

        // top down list
        let expectedFrames = [
            {functionName: 'a', thisValue: ['aThis', 2], isTailDeleted: false},
            {functionName: 'b', thisValue: ['bThis', 1], isTailDeleted: true},
            {functionName: 'c', thisValue: ['cThis', 0], isTailDeleted: true}
        ];

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

        InspectorTest.assert(callFrames.length >= expectedFrames.length);

        // Resolve a thisObject preview on each of the CallFrames.
        let promises = [];
        for (let callFrame of callFrames) {
            InspectorTest.assert(!callFrame.thisObject.preview, "thisObject should not have a preview");
            if (callFrame.thisObject.canLoadPreview()) {
                promises.push(new Promise((resolve, reject) => {
                    callFrame.thisObject.updatePreview(resolve);
                }));
            }
        }

        Promise.all(promises).then(() => {
            for (let i = 0; i < expectedFrames.length; i++) {
                let callFrame = callFrames[i];
                let expectedFrame = expectedFrames[i];
                InspectorTest.log("Expected frame: " + JSON.stringify(expectedFrame));
                InspectorTest.assert(callFrame.functionName === expectedFrame.functionName);
                InspectorTest.assert(callFrame.isTailDeleted === expectedFrame.isTailDeleted);

                let thisObject = callFrame.thisObject;
                let properties = thisObject.preview.propertyPreviews;
                InspectorTest.assert(properties.length === 1);
                let prop = properties[0];
                InspectorTest.expectThat(expectedFrame.thisValue[0] === prop.name, `'this' value should have expected property: ${expectedFrame.thisValue[0]}`);
                InspectorTest.assert('' + expectedFrame.thisValue[1] === prop.value, `'this' value object should have expected property value: ${expectedFrame.thisValue[1]}`);
                InspectorTest.pass(`Call Frame ${i} 'this' value is correct.`);
            }

            WI.debuggerManager.resume();
        });
    });

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

    WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ScriptAdded, function(event) {
        eventScriptObject = event.data.script;
        
        if (/tail-deleted-frames-this-value\.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 and their this values.</p>
</body>
</html>
