<!DOCTYPE html>
<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script src="resources/paused-scopes.js"></script>
<script>
function test()
{
    function scopeTypeName(type) {
        switch (type) {
            case WI.ScopeChainNode.Type.Local: return "Local";
            case WI.ScopeChainNode.Type.Global: return "Global";
            case WI.ScopeChainNode.Type.GlobalLexicalEnvironment: return "GlobalLexicalEnvironment";
            case WI.ScopeChainNode.Type.With: return "With";
            case WI.ScopeChainNode.Type.Closure: return "Closure";
            case WI.ScopeChainNode.Type.Catch: return "Catch";
            case WI.ScopeChainNode.Type.FunctionName: return "FunctionName";
            case WI.ScopeChainNode.Type.Block: return "Block";
            default: return "Unknown!";
        };
    }

    function sanitizeHash(hash) {
        return hash.replace(/:(.*?):/, ":<sourceID>:");
    }

    function collectScopeChainProperties(scopeChain) {
        let scopeChainData = [];

        let promises = [];
        for (let scope of scopeChain) {
            let data = {scope, properties: []};
            scopeChainData.push(data);
            if (scope.type === WI.ScopeChainNode.Type.Global)
                continue;

            for (let scopeObject of scope.objects) {
                promises.push(new Promise((resolve, reject) => {
                    scopeObject.getPropertyDescriptors((propertyDescriptors) => {
                        data.properties = data.properties.concat(propertyDescriptors);
                        resolve();
                    });
                }));
            }
        }

        return Promise.all(promises)
            .then(() => scopeChainData);
    }

    function dumpScopeChainData(scopeChainData) {
        for (let {scope, properties} of scopeChainData) {
            InspectorTest.log(`  SCOPE: Name (${scope.name}) - Type (${scopeTypeName(scope.type)}) - Hash (${sanitizeHash(scope.hash)})`);
            for (let propertyDescriptor of properties)
                InspectorTest.log(`    - ${propertyDescriptor.name}`);
        }
    }

    function dumpCallFrame(callFrame) {
        return Promise.all([
            collectScopeChainProperties(callFrame.scopeChain),
            collectScopeChainProperties(callFrame.mergedScopeChain()),
        ]).then((results) => {
            let [scopeChainData, mergedScopeChainData] = results;
            InspectorTest.log(`CALLFRAME: ${callFrame.functionName}`);
            InspectorTest.log("\n---- Scope Chain ----");
            dumpScopeChainData(scopeChainData);
            InspectorTest.log("\n---- Merged Scope Chain ----");
            dumpScopeChainData(mergedScopeChainData);
            InspectorTest.log("");
        });
    }

    function dumpCallFrames() {
        let targetData = WI.debuggerManager.dataForTarget(WI.debuggerManager.activeCallFrame.target);
        let callFrames = targetData.callFrames;
        let chain = Promise.resolve();
        for (let callFrame of callFrames)
            chain = chain.then(() => dumpCallFrame(callFrame));
        return chain;
    }


    let suite = InspectorTest.createAsyncSuite("PausedCallFrameScope");

    suite.addTestCase({
        name: "PausedCallFrameScope.TriggerFirstPause",
        description: "Dump CallFrames and Scopes with the first pause.",
        test(resolve, reject) {
            InspectorTest.evaluateInPage("setTimeout(entry)");
            WI.debuggerManager.singleFireEventListener(WI.DebuggerManager.Event.Paused, (event) => {
                dumpCallFrames().then(resolve, reject);
            });
        }
    });

    suite.addTestCase({
        name: "PausedCallFrameScope.TriggerSecondPause",
        description: "Dump CallFrames and Scopes with the second pause.",
        test(resolve, reject) {
            WI.debuggerManager.resume();
            WI.debuggerManager.singleFireEventListener(WI.DebuggerManager.Event.Paused, (event) => {
                dumpCallFrames().then(resolve, reject);
            });
        }
    });

    suite.addTestCase({
        name: "PausedCallFrameScope.TriggerThirdPause",
        description: "Dump CallFrames and Scopes with the third pause.",
        test(resolve, reject) {
            WI.debuggerManager.resume();
            WI.debuggerManager.singleFireEventListener(WI.DebuggerManager.Event.Paused, (event) => {
                dumpCallFrames().then(resolve, reject);
            });
        }
    });

    suite.addTestCase({
        name: "PausedCallFrameScope.Complete",
        test(resolve, reject) {
            WI.debuggerManager.resume().then(resolve, reject);
        }
    });

    suite.runTestCasesAndFinish();
}
</script>
</head>
<body onload="runTest()">
<p>Check scope chains for different call frames at different pauses.</p>
</body>
</html>
