<html>
<head>
<script src="../../http/tests/inspector/resources/protocol-test.js"></script>
<script>

function addCompositedLayer()
{
    var element = document.createElement("div");
    element.className = "composited";
    element.id = "last-element";
    document.body.appendChild(element);
    return new Promise(resolve => requestAnimationFrame(resolve));
};

function test()
{
    let documentNode;
    let initialLayers;

    step({
        name: "Enable the LayerTree agent",
        command: "LayerTree.enable",
        parameters: {},
        callback: () => {}
    });

    InspectorProtocol.awaitEvent({event: "LayerTree.layerTreeDidChange"}).then(getDocument);

    function getDocument()
    {
        step({
            name: "Get the Document",
            command: "DOM.getDocument",
            parameters: {},
            callback: getInitialLayerTree
        });
    };
    
    function getInitialLayerTree(result)
    {
        documentNode = result.root;
        step({
            name: "Get the initial layer tree",
            command: "LayerTree.layersForNode",
            parameters: {"nodeId": documentNode.nodeId},
            callback: gotInitialLayerTree
        });
    };

    function gotInitialLayerTree(result)
    {
        initialLayers = result.layers;

        dumpLayers(initialLayers);

        step({
            name: "Message the page to add a new composited layer",
            command: "Runtime.evaluate",
            parameters: {"expression": "addCompositedLayer()"},
            callback: awaitRequestAnimationFrame
        });
    };

    function awaitRequestAnimationFrame(result)
    {
        step({
            name: "Wait for requestAnimationFrame",
            command: "Runtime.awaitPromise",
            parameters: {"promiseObjectId": result.result.objectId},
            callback: getModifiedLayerTree
        });
    };

    function getModifiedLayerTree(result)
    {
        step({
            name: "Get the modified layer tree",
            command: "LayerTree.layersForNode",
            parameters: {"nodeId": documentNode.nodeId},
            callback: gotModifiedLayerTree
        });
    };

    var layerCount = 0;

    function gotModifiedLayerTree(result)
    {
        dumpLayers(result.layers);

        var mutations = layerMutations(initialLayers, result.layers);
        var newLayer = mutations.additions[0];

        step({
            name: "Get attributes for the newly inserted node",
            command: "DOM.getAttributes",
            parameters: {"nodeId": newLayer.nodeId},
            callback: gotNodeAttributes
        });
    };

    function gotNodeAttributes(result)
    {
        var attributes = attributesDictionaryFromArray(result.attributes);
        if (attributes.id !== "last-element")
            ProtocolTest.log("FAIL: Did not obtain the expected element for the last inserted layer.");

        finishTest();
    };

    function finishTest()
    {
        ProtocolTest.log("\n=== Test complete, all expected conditions met ===");
        ProtocolTest.completeTest();
    };

    function layerMutations(oldLayers, newLayers)
    {
        function layerIdMap(layer) {
            return layer.layerId;
        }

        var oldLayerIds = oldLayers.map(layerIdMap);
        var newLayerIds = newLayers.map(layerIdMap);

        return {
            additions: newLayers.filter(function (layer) {
                return (oldLayerIds.indexOf(layer.layerId) === -1);
            }),
            removals: oldLayers.filter(function (layer) {
                return (newLayerIds.indexOf(layer.layerId) === -1);
            })
        };
    };

    function attributesDictionaryFromArray(attributes)
    {
        var dictionary = {}
        for (var i = 0, count = attributes.length; i < count; i += 2) {
            dictionary[attributes[i]] = attributes[i + 1];
        }
        return dictionary;
    };

    function dumpLayers(layers)
    {
        function replacer(key, value)
        {
            if (key === "layerId" || key === "nodeId" || key === "memory" || key === "paintCount")
                return typeof(value);

            // some values differ based on port, but the ones we most
            // care about will always be less or equal 100.
            if ((key === "width" || key === "height") && value > 100) 
                return typeof(value);
            
            return value;
        };
        
        ProtocolTest.log("\n" + JSON.stringify(layers, replacer, "    "));
    };

    function step(test)
    {
        ProtocolTest.log("\n=== " + test.name + " ===\n")
        InspectorProtocol.sendCommand(test.command, test.parameters, function(messageObject) {
            if (messageObject.hasOwnProperty("error")) {
                ProtocolTest.log("FAIL: " + messageObject.error.message + " (" + messageObject.error.code + ")");
                ProtocolTest.completeTest();
                return;
            }

            ProtocolTest.log("PASS");
            test.callback(messageObject.result);
        });
    };

    function assert(name, actual, expected)
    {
        if (expected === actual)
            ProtocolTest.log("PASS: " + name + ".");
        else
            ProtocolTest.log("FAIL: " + name + ". Expected " + expected + " but got " + actual);
    };

};

window.addEventListener("DOMContentLoaded", function () {
    runTest();
}, false);

</script>
<style type="text/css">
      
    div {
        position: absolute;
        top: 0;
        left: 0;
    }
      
    .regular {
        width: 100px;
        height: 100px;
        background-color: black;
    }

    .composited {
        top: 25px;
        left: 25px;
        width: 50px;
        height: 50px;
        background-color: blue;
        -webkit-transform: translateZ(0);
    }
      
    .offset {
        left: 200px;
        -webkit-transform: translateZ(0);
    }

</style>
</head>
<body>

    <div class="regular"></div>

    <div class="composited">
        <div class="composited"></div>
    </div>

    <div class="regular offset">
        <div class="composited"></div>
    </div>

</body>
</html>
