<!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.JavaScriptBreakpoint(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', 3], isTailDeleted: false},
            {functionName: 'b', thisValue: ['bThis', 2], isTailDeleted: true},
            {functionName: 'c', thisValue: ['cThis', 1], isTailDeleted: true}
        ];

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

        InspectorTest.assert(callFrames.length >= expectedFrames.length, `Should have at least ${expectedFrames.length} frames, but have ${callFrames.length} instead.`);

        // 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, `Should have functionName of '${expectedFrame.functionName}', but have '${callFrame.functionName}' instead.`);
                InspectorTest.assert(callFrame.isTailDeleted === expectedFrame.isTailDeleted, `Should have isTailDeleted of '${expectedFrame.isTailDeleted}', but have '${callFrame.isTailDeleted}' instead.`);

                let thisObject = callFrame.thisObject;
                let properties = thisObject.preview.propertyPreviews;
                InspectorTest.assert(properties.length === 1, "Should have one property.");
                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>
