/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.eclipse.org/org/documents/epl-v10.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.ide.eclipse.adt.internal.editors.layout.gle2;

import com.android.ide.common.rendering.api.Capability;
import com.android.ide.common.rendering.api.DataBindingItem;
import com.android.ide.common.rendering.api.MergeCookie;
import com.android.ide.common.rendering.api.ViewInfo;
import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor;
import com.android.ide.eclipse.adt.internal.editors.layout.uimodel.UiViewElementNode;
import com.android.utils.Pair;

import org.eclipse.swt.graphics.Rectangle;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import junit.framework.TestCase;

@SuppressWarnings("javadoc")
public class CanvasViewInfoTest extends TestCase {

    public static ViewElementDescriptor createDesc(String name, String fqn, boolean hasChildren) {
        if (hasChildren) {
            return new ViewElementDescriptor(name, name, fqn, "", "", new AttributeDescriptor[0],
                    new AttributeDescriptor[0], new ElementDescriptor[1], false);
        } else {
            return new ViewElementDescriptor(name, fqn);
        }
    }

    public static UiViewElementNode createNode(UiViewElementNode parent, String fqn,
            boolean hasChildren) {
        String name = fqn.substring(fqn.lastIndexOf('.') + 1);
        ViewElementDescriptor descriptor = createDesc(name, fqn, hasChildren);
        if (parent == null) {
            // All node hierarchies should be wrapped inside a document node at the root
            parent = new UiViewElementNode(createDesc("doc", "doc", true));
        }
        return (UiViewElementNode) parent.appendNewUiChild(descriptor);
    }

    public static UiViewElementNode createNode(String fqn, boolean hasChildren) {
        return createNode(null, fqn, hasChildren);
    }

    public void testNormalCreate() throws Exception {
        normal(true);
    }

    public void testNormalCreateLayoutLib5() throws Exception {
        normal(false);
    }

    private void normal(boolean layoutlib5) {

        // Normal view hierarchy, no null keys anywhere

        UiViewElementNode rootNode = createNode("android.widget.LinearLayout", true);
        ViewInfo root = new ViewInfo("LinearLayout", rootNode, 10, 10, 100, 100);
        UiViewElementNode child1Node = createNode(rootNode, "android.widget.Button", false);
        ViewInfo child1 = new ViewInfo("Button", child1Node, 0, 0, 50, 20);
        UiViewElementNode child2Node = createNode(rootNode, "android.widget.Button", false);
        ViewInfo child2 = new ViewInfo("Button", child2Node, 0, 20, 70, 25);
        root.setChildren(Arrays.asList(child1, child2));

        CanvasViewInfo rootView = CanvasViewInfo.create(root, layoutlib5).getFirst();
        assertNotNull(rootView);
        assertEquals("LinearLayout", rootView.getName());
        assertEquals(new Rectangle(10, 10, 89, 89), rootView.getAbsRect());
        assertEquals(new Rectangle(10, 10, 89, 89), rootView.getSelectionRect());
        assertNull(rootView.getParent());
        assertSame(rootView.getUiViewNode(), rootNode);
        assertEquals(2, rootView.getChildren().size());
        CanvasViewInfo childView1 = rootView.getChildren().get(0);
        CanvasViewInfo childView2 = rootView.getChildren().get(1);

        assertEquals("Button", childView1.getName());
        assertSame(rootView, childView1.getParent());
        assertEquals(new Rectangle(10, 10, 49, 19), childView1.getAbsRect());
        assertEquals(new Rectangle(10, 10, 49, 19), childView1.getSelectionRect());
        assertSame(childView1.getUiViewNode(), child1Node);

        assertEquals("Button", childView2.getName());
        assertSame(rootView, childView2.getParent());
        assertEquals(new Rectangle(10, 30, 69, 4), childView2.getAbsRect());
        assertEquals(new Rectangle(10, 30, 69, 5), childView2.getSelectionRect());
        assertSame(childView2.getUiViewNode(), child2Node);
    }

    public void testShowIn() throws Exception {
        showIn(false);
    }

    public void testShowInLayoutLib5() throws Exception {
        showIn(true);
    }

    public void showIn(boolean layoutlib5) throws Exception {

        // Test rendering of "Show Included In" (included content rendered
        // within an outer content that has null keys)

        ViewInfo root = new ViewInfo("LinearLayout", null, 10, 10, 100, 100);
        ViewInfo child1 = new ViewInfo("CheckBox", null, 0, 0, 50, 20);
        UiViewElementNode child2Node = createNode("android.widget.RelativeLayout", true);
        ViewInfo child2 = new ViewInfo("RelativeLayout", child2Node, 0, 20, 70, 25);
        root.setChildren(Arrays.asList(child1, child2));
        UiViewElementNode child21Node = createNode("android.widget.Button", false);
        ViewInfo child21 = new ViewInfo("RadioButton", child21Node, 0, 20, 70, 25);
        child2.setChildren(Arrays.asList(child21));

        CanvasViewInfo rootView = CanvasViewInfo.create(root, layoutlib5).getFirst();
        assertNotNull(rootView);
        assertEquals("LinearLayout", rootView.getName());
        assertEquals(new Rectangle(10, 10, 89, 89), rootView.getAbsRect());
        assertEquals(new Rectangle(10, 10, 89, 89), rootView.getSelectionRect());
        assertNull(rootView.getParent());
        assertNull(rootView.getUiViewNode());
        assertEquals(1, rootView.getChildren().size());
        CanvasViewInfo includedView = rootView.getChildren().get(0);

        assertEquals("RelativeLayout", includedView.getName());
        assertSame(rootView, includedView.getParent());
        assertEquals(new Rectangle(10, 30, 69, 4), includedView.getAbsRect());
        assertEquals(new Rectangle(10, 30, 69, 5), includedView.getSelectionRect());
        assertSame(includedView.getUiViewNode(), child2Node);

        CanvasViewInfo grandChild = includedView.getChildren().get(0);
        assertNotNull(grandChild);
        assertEquals("RadioButton", grandChild.getName());
        assertSame(child21Node, grandChild.getUiViewNode());
        assertEquals(new Rectangle(10, 50, 69, 4), grandChild.getAbsRect());
        assertEquals(new Rectangle(10, 50, 69, 5), grandChild.getSelectionRect());
    }

    public void testIncludeTag() throws Exception {
        boolean layoutlib5 = true;

        // Test rendering of included views on layoutlib 5+ (e.g. has <include> tag)

        UiViewElementNode rootNode = createNode("android.widget.LinearLayout", true);
        ViewInfo root = new ViewInfo("LinearLayout", rootNode, 10, 10, 100, 100);
        UiViewElementNode child1Node = createNode(rootNode, "android.widget.Button", false);
        ViewInfo child1 = new ViewInfo("CheckBox", child1Node, 0, 0, 50, 20);
        UiViewElementNode child2Node = createNode(rootNode, "include", true);
        ViewInfo child2 = new ViewInfo("RelativeLayout", child2Node, 0, 20, 70, 25);
        root.setChildren(Arrays.asList(child1, child2));
        ViewInfo child21 = new ViewInfo("RadioButton", null, 0, 20, 70, 25);
        child2.setChildren(Arrays.asList(child21));

        CanvasViewInfo rootView = CanvasViewInfo.create(root, layoutlib5).getFirst();
        assertNotNull(rootView);
        assertEquals("LinearLayout", rootView.getName());
        assertEquals(new Rectangle(10, 10, 89, 89), rootView.getAbsRect());
        assertEquals(new Rectangle(10, 10, 89, 89), rootView.getSelectionRect());
        assertNull(rootView.getParent());
        assertSame(rootNode, rootView.getUiViewNode());
        assertEquals(2, rootView.getChildren().size());

        CanvasViewInfo childView1 = rootView.getChildren().get(0);
        CanvasViewInfo includedView = rootView.getChildren().get(1);

        assertEquals("CheckBox", childView1.getName());
        assertSame(rootView, childView1.getParent());
        assertEquals(new Rectangle(10, 10, 49, 19), childView1.getAbsRect());
        assertEquals(new Rectangle(10, 10, 49, 19), childView1.getSelectionRect());
        assertSame(childView1.getUiViewNode(), child1Node);

        assertEquals("RelativeLayout", includedView.getName());
        assertSame(rootView, includedView.getParent());
        assertEquals(new Rectangle(10, 30, 69, 4), includedView.getAbsRect());
        assertEquals(new Rectangle(10, 30, 69, 5), includedView.getSelectionRect());
        assertSame(includedView.getUiViewNode(), child2Node);
        assertEquals(0, includedView.getChildren().size());
    }

    public void testNoIncludeTag() throws Exception {
        boolean layoutlib5 = false;

        // Test rendering of included views on layoutlib 4- (e.g. no <include> tag cookie
        // in view info)

        UiViewElementNode rootNode = createNode("android.widget.LinearLayout", true);
        ViewInfo root = new ViewInfo("LinearLayout", rootNode, 10, 10, 100, 100);
        UiViewElementNode child1Node = createNode(rootNode, "android.widget.Button", false);
        ViewInfo child1 = new ViewInfo("CheckBox", child1Node, 0, 0, 50, 20);
        UiViewElementNode child2Node = createNode(rootNode, "include", true);
        ViewInfo child2 = new ViewInfo("RelativeLayout", null /* layoutlib 4 */, 0, 20, 70, 25);
        root.setChildren(Arrays.asList(child1, child2));
        ViewInfo child21 = new ViewInfo("RadioButton", null, 0, 20, 70, 25);
        child2.setChildren(Arrays.asList(child21));

        CanvasViewInfo rootView = CanvasViewInfo.create(root, layoutlib5).getFirst();
        assertNotNull(rootView);
        assertEquals("LinearLayout", rootView.getName());
        assertEquals(new Rectangle(10, 10, 89, 89), rootView.getAbsRect());
        assertEquals(new Rectangle(10, 10, 89, 89), rootView.getSelectionRect());
        assertNull(rootView.getParent());
        assertSame(rootNode, rootView.getUiViewNode());
        assertEquals(2, rootView.getChildren().size());

        CanvasViewInfo childView1 = rootView.getChildren().get(0);
        CanvasViewInfo includedView = rootView.getChildren().get(1);

        assertEquals("CheckBox", childView1.getName());
        assertSame(rootView, childView1.getParent());
        assertEquals(new Rectangle(10, 10, 49, 19), childView1.getAbsRect());
        assertEquals(new Rectangle(10, 10, 49, 19), childView1.getSelectionRect());
        assertSame(childView1.getUiViewNode(), child1Node);

        assertEquals("RelativeLayout", includedView.getName());
        assertSame(rootView, includedView.getParent());
        assertEquals(new Rectangle(10, 30, 69, 4), includedView.getAbsRect());
        assertEquals(new Rectangle(10, 30, 69, 5), includedView.getSelectionRect());
        assertSame(includedView.getUiViewNode(), child2Node);
        assertEquals(0, includedView.getChildren().size());
    }

    public void testMergeMatching() throws Exception {
        boolean layoutlib5 = false;

        // Test rendering of MULTIPLE included views or when there is no simple match
        // between view info and ui element node children

        UiViewElementNode rootNode = createNode("android.widget.LinearLayout", true);
        ViewInfo root = new ViewInfo("LinearLayout", rootNode, 10, 10, 100, 100);
        UiViewElementNode child1Node = createNode(rootNode, "android.widget.Button", false);
        ViewInfo child1 = new ViewInfo("CheckBox", child1Node, 0, 0, 50, 20);
        UiViewElementNode multiChildNode1 = createNode(rootNode, "foo", true);
        UiViewElementNode multiChildNode2 = createNode(rootNode, "bar", true);
        ViewInfo child2 = new ViewInfo("RelativeLayout", null, 0, 20, 70, 25);
        ViewInfo child3 = new ViewInfo("AbsoluteLayout", null, 10, 40, 50, 15);
        root.setChildren(Arrays.asList(child1, child2, child3));
        ViewInfo child21 = new ViewInfo("RadioButton", null, 0, 20, 70, 25);
        child2.setChildren(Arrays.asList(child21));

        CanvasViewInfo rootView = CanvasViewInfo.create(root, layoutlib5).getFirst();
        assertNotNull(rootView);
        assertEquals("LinearLayout", rootView.getName());
        assertEquals(new Rectangle(10, 10, 89, 89), rootView.getAbsRect());
        assertEquals(new Rectangle(10, 10, 89, 89), rootView.getSelectionRect());
        assertNull(rootView.getParent());
        assertTrue(rootView.isRoot());
        assertSame(rootNode, rootView.getUiViewNode());
        assertEquals(3, rootView.getChildren().size());

        CanvasViewInfo childView1 = rootView.getChildren().get(0);
        assertFalse(childView1.isRoot());
        CanvasViewInfo includedView1 = rootView.getChildren().get(1);
        assertFalse(includedView1.isRoot());
        CanvasViewInfo includedView2 = rootView.getChildren().get(2);
        assertFalse(includedView1.isRoot());

        assertEquals("CheckBox", childView1.getName());
        assertSame(rootView, childView1.getParent());
        assertEquals(new Rectangle(10, 10, 49, 19), childView1.getAbsRect());
        assertEquals(new Rectangle(10, 10, 49, 19), childView1.getSelectionRect());
        assertSame(childView1.getUiViewNode(), child1Node);

        assertEquals("RelativeLayout", includedView1.getName());
        assertSame(multiChildNode1, includedView1.getUiViewNode());
        assertEquals("foo", includedView1.getUiViewNode().getDescriptor().getXmlName());
        assertSame(multiChildNode2, includedView2.getUiViewNode());
        assertEquals("AbsoluteLayout", includedView2.getName());
        assertEquals("bar", includedView2.getUiViewNode().getDescriptor().getXmlName());
        assertSame(rootView, includedView1.getParent());
        assertSame(rootView, includedView2.getParent());
        assertEquals(new Rectangle(10, 30, 69, 4), includedView1.getAbsRect());
        assertEquals(new Rectangle(10, 30, 69, 5), includedView1.getSelectionRect());
        assertEquals(new Rectangle(20, 50, 39, -26), includedView2.getAbsRect());
        assertEquals(new Rectangle(20, 35, 39, 5), includedView2.getSelectionRect());
        assertEquals(0, includedView1.getChildren().size());
        assertEquals(0, includedView2.getChildren().size());
    }

    public void testMerge() throws Exception {
        boolean layoutlib5 = false;

        // Test rendering of MULTIPLE included views or when there is no simple match
        // between view info and ui element node children

        UiViewElementNode rootNode = createNode("android.widget.LinearLayout", true);
        ViewInfo root = new ViewInfo("LinearLayout", rootNode, 10, 10, 100, 100);
        UiViewElementNode child1Node = createNode(rootNode, "android.widget.Button", false);
        ViewInfo child1 = new ViewInfo("CheckBox", child1Node, 0, 0, 50, 20);
        UiViewElementNode multiChildNode = createNode(rootNode, "foo", true);
        ViewInfo child2 = new ViewInfo("RelativeLayout", null, 0, 20, 70, 25);
        ViewInfo child3 = new ViewInfo("AbsoluteLayout", null, 10, 40, 50, 15);
        root.setChildren(Arrays.asList(child1, child2, child3));
        ViewInfo child21 = new ViewInfo("RadioButton", null, 0, 20, 70, 25);
        child2.setChildren(Arrays.asList(child21));

        CanvasViewInfo rootView = CanvasViewInfo.create(root, layoutlib5).getFirst();
        assertNotNull(rootView);
        assertEquals("LinearLayout", rootView.getName());
        assertEquals(new Rectangle(10, 10, 89, 89), rootView.getAbsRect());
        assertEquals(new Rectangle(10, 10, 89, 89), rootView.getSelectionRect());
        assertNull(rootView.getParent());
        assertSame(rootNode, rootView.getUiViewNode());
        assertEquals(2, rootView.getChildren().size());

        CanvasViewInfo childView1 = rootView.getChildren().get(0);
        CanvasViewInfo includedView = rootView.getChildren().get(1);

        assertEquals("CheckBox", childView1.getName());
        assertSame(rootView, childView1.getParent());
        assertEquals(new Rectangle(10, 10, 49, 19), childView1.getAbsRect());
        assertEquals(new Rectangle(10, 10, 49, 19), childView1.getSelectionRect());
        assertSame(childView1.getUiViewNode(), child1Node);

        assertEquals("RelativeLayout", includedView.getName());
        assertSame(rootView, includedView.getParent());
        assertEquals(new Rectangle(10, 30, 69, 4), includedView.getAbsRect());
        assertEquals(new Rectangle(10, 30, 69, 5), includedView.getSelectionRect());
        assertEquals(0, includedView.getChildren().size());
        assertSame(multiChildNode, includedView.getUiViewNode());
    }

    public void testInsertMerge() throws Exception {
        boolean layoutlib5 = false;

        // Test rendering of MULTIPLE included views or when there is no simple match
        // between view info and ui element node children

        UiViewElementNode mergeNode = createNode("merge", true);
        UiViewElementNode rootNode = createNode(mergeNode, "android.widget.Button", false);
        ViewInfo root = new ViewInfo("Button", rootNode, 10, 10, 100, 100);

        CanvasViewInfo rootView = CanvasViewInfo.create(root, layoutlib5).getFirst();
        assertNotNull(rootView);
        assertEquals("merge", rootView.getName());
        assertSame(rootView.getUiViewNode(), mergeNode);
        assertEquals(new Rectangle(10, 10, 89, 89), rootView.getAbsRect());
        assertEquals(new Rectangle(10, 10, 89, 89), rootView.getSelectionRect());
        assertNull(rootView.getParent());
        assertSame(mergeNode, rootView.getUiViewNode());
        assertEquals(1, rootView.getChildren().size());

        CanvasViewInfo childView1 = rootView.getChildren().get(0);

        assertEquals("Button", childView1.getName());
        assertSame(rootView, childView1.getParent());
        assertEquals(new Rectangle(10, 10, 89, 89), childView1.getAbsRect());
        assertEquals(new Rectangle(10, 10, 89, 89), childView1.getSelectionRect());
        assertSame(childView1.getUiViewNode(), rootNode);
    }

    public void testUnmatchedMissing() throws Exception {
        boolean layoutlib5 = false;

        UiViewElementNode rootNode = createNode("android.widget.LinearLayout", true);
        ViewInfo root = new ViewInfo("LinearLayout", rootNode, 0, 0, 100, 100);
        List<ViewInfo> children = new ArrayList<ViewInfo>();
        // Should be matched up with corresponding node:
        Set<Integer> missingKeys = new HashSet<Integer>();
        // Should not be matched with any views, but should get view created:
        Set<Integer> extraKeys = new HashSet<Integer>();
        // Should not be matched with any nodes
        Set<Integer> extraViews = new HashSet<Integer>();
        int numViews = 30;
        missingKeys.add(0);
        missingKeys.add(4);
        missingKeys.add(14);
        missingKeys.add(29);
        extraKeys.add(9);
        extraKeys.add(20);
        extraKeys.add(22);
        extraViews.add(18);
        extraViews.add(24);

        List<String> expectedViewNames = new ArrayList<String>();
        List<String> expectedNodeNames = new ArrayList<String>();

        for (int i = 0; i < numViews; i++) {
            UiViewElementNode childNode = null;
            if (!extraViews.contains(i)) {
                childNode = createNode(rootNode, "childNode" + i, false);
            }
            Object cookie = missingKeys.contains(i) || extraViews.contains(i) ? null : childNode;
            ViewInfo childView = new ViewInfo("childView" + i, cookie,
                    0, i * 20, 50, (i + 1) * 20);
            children.add(childView);

            if (!extraViews.contains(i)) {
                expectedViewNames.add("childView" + i);
                expectedNodeNames.add("childNode" + i);
            }

            if (extraKeys.contains(i)) {
                createNode(rootNode, "extraNodeAt" + i, false);

                expectedViewNames.add("extraNodeAt" + i);
                expectedNodeNames.add("extraNodeAt" + i);
            }
        }
        root.setChildren(children);

        CanvasViewInfo rootView = CanvasViewInfo.create(root, layoutlib5).getFirst();
        assertNotNull(rootView);

        // dump(root, 0);
        // dump(rootView, 0);

        assertEquals("LinearLayout", rootView.getName());
        assertNull(rootView.getParent());
        assertSame(rootNode, rootView.getUiViewNode());
        assertEquals(numViews + extraKeys.size() - extraViews.size(), rootNode.getUiChildren()
                .size());
        assertEquals(numViews + extraKeys.size() - extraViews.size(),
                rootView.getChildren().size());
        assertEquals(expectedViewNames.size(), rootView.getChildren().size());
        for (int i = 0, n = rootView.getChildren().size(); i < n; i++) {
            CanvasViewInfo childView = rootView.getChildren().get(i);
            String expectedViewName = expectedViewNames.get(i);
            String expectedNodeName = expectedNodeNames.get(i);
            assertEquals(expectedViewName, childView.getName());
            assertNotNull(childView.getUiViewNode());
            assertEquals(expectedNodeName, childView.getUiViewNode().getDescriptor().getXmlName());
        }
    }

    public void testMergeCookies() throws Exception {
        boolean layoutlib5 = true;

        UiViewElementNode rootNode = createNode("android.widget.LinearLayout", true);
        ViewInfo root = new ViewInfo("LinearLayout", rootNode, 0, 0, 100, 100);

        // Create the merge cookies in the opposite order to ensure that we don't
        // apply our own logic when matching up views with nodes
        LinkedList<MergeCookie> cookies = new LinkedList<MergeCookie>();
        for (int i = 0; i < 10; i++) {
            UiViewElementNode node = createNode(rootNode, "childNode" + i, false);
            cookies.addFirst(new MergeCookie(node));
        }
        Iterator<MergeCookie> it = cookies.iterator();
        ArrayList<ViewInfo> children = new ArrayList<ViewInfo>();
        for (int i = 0; i < 10; i++) {
            ViewInfo childView = new ViewInfo("childView" + i, it.next(), 0, i * 20, 50,
                    (i + 1) * 20);
            children.add(childView);
        }
        root.setChildren(children);

        CanvasViewInfo rootView = CanvasViewInfo.create(root, layoutlib5).getFirst();
        assertNotNull(rootView);

        assertEquals("LinearLayout", rootView.getName());
        assertNull(rootView.getParent());
        assertSame(rootNode, rootView.getUiViewNode());
        for (int i = 0, n = rootView.getChildren().size(); i < n; i++) {
            CanvasViewInfo childView = rootView.getChildren().get(i);
            assertEquals("childView" + i, childView.getName());
            assertEquals("childNode" + (9 - i), childView.getUiViewNode().getDescriptor()
                    .getXmlName());
        }
    }

    public void testMergeCookies2() throws Exception {
        boolean layoutlib5 = true;

        UiViewElementNode rootNode = createNode("android.widget.LinearLayout", true);
        ViewInfo root = new ViewInfo("LinearLayout", rootNode, 0, 0, 100, 100);

        UiViewElementNode node1 = createNode(rootNode, "childNode1", false);
        UiViewElementNode node2 = createNode(rootNode, "childNode2", false);
        MergeCookie cookie1 = new MergeCookie(node1);
        MergeCookie cookie2 = new MergeCookie(node2);

        // Sets alternating merge cookies and checks whether the node sibling lists are
        // okay and merged correctly

        ArrayList<ViewInfo> children = new ArrayList<ViewInfo>();
        for (int i = 0; i < 10; i++) {
            Object cookie = (i % 2) == 0 ? cookie1 : cookie2;
            ViewInfo childView = new ViewInfo("childView" + i, cookie, 0, i * 20, 50,
                    (i + 1) * 20);
            children.add(childView);
        }
        root.setChildren(children);

        Pair<CanvasViewInfo, List<Rectangle>> result = CanvasViewInfo.create(root, layoutlib5);
        CanvasViewInfo rootView = result.getFirst();
        List<Rectangle> bounds = result.getSecond();
        assertNull(bounds);
        assertNotNull(rootView);

        assertEquals("LinearLayout", rootView.getName());
        assertNull(rootView.getParent());
        assertSame(rootNode, rootView.getUiViewNode());
        assertEquals(10, rootView.getChildren().size());
        assertEquals(2, rootView.getUniqueChildren().size());
        for (int i = 0, n = rootView.getChildren().size(); i < n; i++) {
            CanvasViewInfo childView = rootView.getChildren().get(i);
            assertEquals("childView" + i, childView.getName());
            Object cookie = (i % 2) == 0 ? node1 : node2;
            assertSame(cookie, childView.getUiViewNode());
            List<CanvasViewInfo> nodeSiblings = childView.getNodeSiblings();
            assertEquals(5, nodeSiblings.size());
        }
        List<CanvasViewInfo> nodeSiblings = rootView.getChildren().get(0).getNodeSiblings();
        for (int j = 0; j < 5; j++) {
            assertEquals("childView" + (j * 2), nodeSiblings.get(j).getName());
        }
        nodeSiblings = rootView.getChildren().get(1).getNodeSiblings();
        for (int j = 0; j < 5; j++) {
            assertEquals("childView" + (j * 2 + 1), nodeSiblings.get(j).getName());
        }
    }

    public void testIncludeBounds() throws Exception {
        boolean layoutlib5 = true;

        UiViewElementNode rootNode = createNode("android.widget.LinearLayout", true);
        ViewInfo root = new ViewInfo("included", null, 0, 0, 100, 100);

        UiViewElementNode node1 = createNode(rootNode, "childNode1", false);
        UiViewElementNode node2 = createNode(rootNode, "childNode2", false);
        MergeCookie cookie1 = new MergeCookie(node1);
        MergeCookie cookie2 = new MergeCookie(node2);

        // Sets alternating merge cookies and checks whether the node sibling lists are
        // okay and merged correctly

        ArrayList<ViewInfo> children = new ArrayList<ViewInfo>();
        for (int i = 0; i < 10; i++) {
            Object cookie = (i % 2) == 0 ? cookie1 : cookie2;
            ViewInfo childView = new ViewInfo("childView" + i, cookie, 0, i * 20, 50,
                    (i + 1) * 20);
            children.add(childView);
        }
        root.setChildren(children);

        Pair<CanvasViewInfo, List<Rectangle>> result = CanvasViewInfo.create(root, layoutlib5);
        CanvasViewInfo rootView = result.getFirst();
        List<Rectangle> bounds = result.getSecond();
        assertNotNull(rootView);

        assertEquals("included", rootView.getName());
        assertNull(rootView.getParent());
        assertNull(rootView.getUiViewNode());
        assertEquals(10, rootView.getChildren().size());
        assertEquals(2, rootView.getUniqueChildren().size());
        for (int i = 0, n = rootView.getChildren().size(); i < n; i++) {
            CanvasViewInfo childView = rootView.getChildren().get(i);
            assertEquals("childView" + i, childView.getName());
            Object cookie = (i % 2) == 0 ? node1 : node2;
            assertSame(cookie, childView.getUiViewNode());
            List<CanvasViewInfo> nodeSiblings = childView.getNodeSiblings();
            assertEquals(5, nodeSiblings.size());
        }
        List<CanvasViewInfo> nodeSiblings = rootView.getChildren().get(0).getNodeSiblings();
        for (int j = 0; j < 5; j++) {
            assertEquals("childView" + (j * 2), nodeSiblings.get(j).getName());
        }
        nodeSiblings = rootView.getChildren().get(1).getNodeSiblings();
        for (int j = 0; j < 5; j++) {
            assertEquals("childView" + (j * 2 + 1), nodeSiblings.get(j).getName());
        }

        // Only show the primary bounds as included
        assertEquals(2, bounds.size());
        assertEquals(new Rectangle(0, 0, 49, 19), bounds.get(0));
        assertEquals(new Rectangle(0, 20, 49, 19), bounds.get(1));
    }

    public void testIncludeBounds2() throws Exception {
        includeBounds2(false);
    }

    public void testIncludeBounds2LayoutLib5() throws Exception {
        includeBounds2(true);
    }

    public void includeBounds2(boolean layoutlib5) throws Exception {

        UiViewElementNode rootNode = createNode("android.widget.LinearLayout", true);
        ViewInfo root = new ViewInfo("included", null, 0, 0, 100, 100);

        UiViewElementNode node1 = createNode(rootNode, "childNode1", false);
        UiViewElementNode node2 = createNode(rootNode, "childNode2", false);

        ViewInfo childView1 = new ViewInfo("childView1", node1, 0, 20, 50, 40);
        ViewInfo childView2 = new ViewInfo("childView2", node2, 0, 40, 50, 60);

        root.setChildren(Arrays.asList(childView1, childView2));

        Pair<CanvasViewInfo, List<Rectangle>> result = CanvasViewInfo.create(root, layoutlib5);
        CanvasViewInfo rootView = result.getFirst();
        List<Rectangle> bounds = result.getSecond();
        assertNotNull(rootView);

        assertEquals("included", rootView.getName());
        assertNull(rootView.getParent());
        assertNull(rootView.getUiViewNode());
        assertEquals(2, rootView.getChildren().size());
        assertEquals(2, rootView.getUniqueChildren().size());

        Rectangle bounds1 = bounds.get(0);
        Rectangle bounds2 = bounds.get(1);
        assertEquals(new Rectangle(0, 20, 49, 19), bounds1);
        assertEquals(new Rectangle(0, 40, 49, 19), bounds2);
    }

    public void testCookieWorkaround() throws Exception {
        UiViewElementNode rootNode = createNode("android.widget.LinearLayout", true);
        ViewInfo root = new ViewInfo("included", null, 0, 0, 100, 100);

        UiViewElementNode node2 = createNode(rootNode, "childNode2", false);
        MergeCookie mergeCookie = new MergeCookie(root);

        ViewInfo childView1 = new ViewInfo("childView1", mergeCookie, 0, 20, 50, 40);
        ViewInfo childView2 = new ViewInfo("childView2", node2, 0, 40, 50, 60);

        root.setChildren(Arrays.asList(childView1, childView2));

        Pair<CanvasViewInfo, List<Rectangle>> result = CanvasViewInfo.create(root, true);
        CanvasViewInfo rootView = result.getFirst();
        List<Rectangle> bounds = result.getSecond();
        assertNotNull(rootView);

        assertEquals("included", rootView.getName());
        assertNull(rootView.getParent());
        assertNull(rootView.getUiViewNode());
        // childView1 should have been removed since it has the wrong merge cookie
        assertEquals(1, rootView.getChildren().size());
        assertEquals(1, rootView.getUniqueChildren().size());

        Rectangle bounds1 = bounds.get(0);
        assertEquals(new Rectangle(0, 40, 49, 19), bounds1);
    }

    public void testGestureOverlayView() throws Exception {
        boolean layoutlib5 = true;

        // Test rendering of included views on layoutlib 5+ (e.g. has <include> tag)

        UiViewElementNode rootNode = createNode("android.gesture.GestureOverlayView", true);
        UiViewElementNode childNode = createNode(rootNode, "android.widget.LinearLayout", false);
        UiViewElementNode grandChildNode = createNode(childNode, "android.widget.Button", false);
        ViewInfo root = new ViewInfo("GestureOverlayView", rootNode, 10, 10, 100, 100);
        ViewInfo child = new ViewInfo("LinearLayout", childNode, 0, 0, 50, 20);
        root.setChildren(Collections.singletonList(child));
        ViewInfo grandChild = new ViewInfo("Button", grandChildNode, 0, 20, 70, 25);
        child.setChildren(Collections.singletonList(grandChild));
        CanvasViewInfo rootView = CanvasViewInfo.create(root, layoutlib5).getFirst();
        assertNotNull(rootView);
        assertEquals("GestureOverlayView", rootView.getName());

        assertTrue(rootView.isRoot());
        assertNull(rootView.getParent());
        assertSame(rootNode, rootView.getUiViewNode());
        assertEquals(1, rootView.getChildren().size());

        CanvasViewInfo childView = rootView.getChildren().get(0);
        assertEquals("LinearLayout", childView.getName());

        // This should also be a root for the special case that the root is
        assertTrue(childView.isRoot());

        assertEquals(1, childView.getChildren().size());
        CanvasViewInfo grandChildView = childView.getChildren().get(0);
        assertEquals("Button", grandChildView.getName());
        assertFalse(grandChildView.isRoot());
    }

    public void testListView() throws Exception {
        // For ListViews we get AdapterItemReferences as cookies. Ensure that this
        // works properly.
        //
        // android.widget.FrameLayout [0,50,320,480] <FrameLayout>
        //     android.widget.ListView [0,0,320,430] <ListView>
        //        android.widget.LinearLayout [0,0,320,17] SessionParams$AdapterItemReference
        //            android.widget.TextView [0,0,73,17]
        //        android.widget.LinearLayout [0,18,320,35] SessionParams$AdapterItemReference
        //            android.widget.TextView [0,0,73,17]
        //        android.widget.LinearLayout [0,36,320,53] SessionParams$AdapterItemReference
        //            android.widget.TextView [0,0,73,17]
        //        ...

        UiViewElementNode rootNode = createNode("FrameLayout", true);
        UiViewElementNode childNode = createNode(rootNode, "ListView", false);
        /*UiViewElementNode grandChildNode =*/ createNode(childNode, "LinearLayout", false);
        /*UiViewElementNode greatGrandChildNode =*/ createNode(childNode, "TextView", false);
        DataBindingItem dataBindingItem = new DataBindingItem("foo");

        ViewInfo root = new ViewInfo("FrameLayout", rootNode, 0, 50, 320, 480);
        ViewInfo child = new ViewInfo("ListView", childNode, 0, 0, 320, 430);
        root.setChildren(Collections.singletonList(child));
        ViewInfo grandChild = new ViewInfo("LinearLayout", dataBindingItem, 0, 0, 320, 17);
        child.setChildren(Collections.singletonList(grandChild));
        ViewInfo greatGrandChild = new ViewInfo("Button", null, 0, 0, 73, 17);
        grandChild.setChildren(Collections.singletonList(greatGrandChild));
        CanvasViewInfo rootView = CanvasViewInfo.create(root, true /*layoutlib5*/).getFirst();
        assertNotNull(rootView);

        assertEquals("FrameLayout", rootView.getName());
        assertEquals(1, rootView.getChildren().size());
        assertSame(rootNode, rootView.getUiViewNode());

        CanvasViewInfo childView = rootView.getChildren().get(0);
        assertEquals("ListView", childView.getName());
        assertEquals(0, childView.getChildren().size());
        assertSame(childNode, childView.getUiViewNode());
    }

    /**
     * Dumps out the given {@link ViewInfo} hierarchy to standard out.
     * Useful during development.
     *
     * @param graphicalEditor the editor associated with this hierarchy
     * @param root the root of the {@link ViewInfo} hierarchy
     */
    public static void dump(GraphicalEditorPart graphicalEditor, ViewInfo root) {
        System.out.println("\n\nRendering:");
        boolean supportsEmbedding = graphicalEditor.renderingSupports(Capability.EMBEDDED_LAYOUT);
        System.out.println("Supports Embedded Layout=" + supportsEmbedding);
        System.out.println("Rendering context=" + graphicalEditor.getIncludedWithin());
        dump(root, 0);
    }

    /** Helper for {@link #dump(GraphicalEditorPart, ViewInfo)} */
    public static void dump(ViewInfo info, int depth) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < depth; i++) {
            sb.append("    ");
        }
        sb.append(info.getClassName());
        sb.append(" [");
        sb.append(info.getLeft());
        sb.append(",");
        sb.append(info.getTop());
        sb.append(",");
        sb.append(info.getRight());
        sb.append(",");
        sb.append(info.getBottom());
        sb.append("] ");
        Object cookie = info.getCookie();
        if (cookie instanceof UiViewElementNode) {
            sb.append(" ");
            UiViewElementNode node = (UiViewElementNode) cookie;
            sb.append("<");
            sb.append(node.getDescriptor().getXmlName());
            sb.append("> ");
        } else if (cookie != null) {
            sb.append(" cookie=" + cookie);
        }

        System.out.println(sb.toString());

        for (ViewInfo child : info.getChildren()) {
            dump(child, depth + 1);
        }
    }

    /** Helper for {@link #dump(GraphicalEditorPart, ViewInfo)} */
    public static void dump(CanvasViewInfo info, int depth) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < depth; i++) {
            sb.append("    ");
        }
        sb.append(info.getName());
        sb.append(" [");
        sb.append(info.getAbsRect());
        sb.append("], node=");
        sb.append(info.getUiViewNode());

        System.out.println(sb.toString());

        for (CanvasViewInfo child : info.getChildren()) {
            dump(child, depth + 1);
        }
    }

}
