/*******************************************************************************
 * Copyright (c) 2004, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.tests.performance;

import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.mapping.ResourceMapping;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.SubContributionItem;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.PluginActionContributionItem;
import org.eclipse.ui.internal.PopupMenuExtender;
import org.eclipse.ui.internal.WorkbenchWindow;
import org.eclipse.ui.tests.harness.util.UITestCase;
import org.eclipse.ui.tests.performance.ObjectContributionClasses.ICommon;
/**
 * Tests that object contributions are enabled and shown correctly in pop-up
 * menus depending on the state of the workbench. This test relies on the
 * <code>plugin.xml</code> file containing certain values. Please see the
 * appropriate section in that file for more information about the initial
 * set-up.
 * 
 * @since 3.0
 */
public final class ObjectContributionTest extends UITestCase {

    /**
     * Constructs a new instance of <code>ObjectContributionTest</code> with
     * the name of the test.
     * 
     * @param name
     *            The name of the test; may be <code>null</code>.
     */
    public ObjectContributionTest(final String name) {
        super(name);
    }

    /**
     * Tests whether the content-type object contribution works. This is testing
     * a use care familiar to Ant UI. The content-type scans an XML file to see
     * if its root element is <code>&lt;project&gt;</code>.
     * 
     * @throws CoreException
     *             If a problem occurs when creating the project or file, or if
     *             the project can't be opened.
     */
    public final void testObjectStateContentType() throws CoreException {
        // Create an XML file with <project> as its root element.
        final IWorkspace workspace = ResourcesPlugin.getWorkspace();
        final IProject testProject = workspace.getRoot().getProject(
                "ObjectContributionTestProject");
        testProject.create(null);
        testProject.open(null);
        final IFile xmlFile = testProject.getFile("ObjectContributionTest.xml");
        final String contents = "<testObjectStateContentTypeElement></testObjectStateContentTypeElement>";
        final ByteArrayInputStream inputStream = new ByteArrayInputStream(
                contents.getBytes());
        xmlFile.create(inputStream, true, null);
        final ISelection selection = new StructuredSelection(xmlFile);
        assertPopupMenus("1", new String[] {"org.eclipse.ui.tests.testObjectStateContentType"}, selection, null, true);
    }
    
    /**
     * This tests backwards compatibility support for adaptable IResource objectContributions. This
     * allows IResource adaptable contributions without an adapter factory and using
     * the IContributorResourceAdapter factory. In addition, test the ResourceMapping adaptations.
     * 
     * @since 3.1
     */
    public final void testContributorResourceAdapter() throws CoreException {
    	
    	final IWorkspace workspace = ResourcesPlugin.getWorkspace();
        final IProject testProject = workspace.getRoot().getProject(ObjectContributionClasses.PROJECT_NAME);
        if(! testProject.exists()) {
        	testProject.create(null);
        }
        if(! testProject.isOpen()) {
        	testProject.open(null);
        }
    	
    	assertPopupMenus("1",
    			new String[] {"IResource.1"}, 
    			new StructuredSelection(new Object[] {new ObjectContributionClasses.CResource()}),
				IResource.class,
				true
			);
    	assertPopupMenus("2",
    			new String[] {"IProject.1"}, 
    			new StructuredSelection(new Object[] {new ObjectContributionClasses.CFile()}),
				null,
				false
			);
    	assertPopupMenus("3", 
    			new String[] {"IFile.1"}, 
    			new StructuredSelection(new Object[] {new ObjectContributionClasses.CFile()}),
				IFile.class,
				true
			);
    	assertPopupMenus("4", 
    			new String[] {"IResource.1"}, 
    			new StructuredSelection(new Object[] {new ObjectContributionClasses.CFile(), new ObjectContributionClasses.CResource()}),
				IResource.class,
				true
			);
    	assertPopupMenus("5", 
    			new String[] {"IFile.1", "IProject.1"}, 
    			new StructuredSelection(new Object[] {new ObjectContributionClasses.CFile(), new ObjectContributionClasses.CResource()}),
				IResource.class,
				false
			);
        assertPopupMenus("6", 
                new String[] {"ResourceMapping.1"}, 
                new StructuredSelection(new Object[] {new ObjectContributionClasses.CFile(), new ObjectContributionClasses.CResource()}),
                ResourceMapping.class,
                true
            );
        assertPopupMenus("7", 
                new String[] {"ResourceMapping.1", "IResource.1"}, 
                new StructuredSelection(new Object[] {new ObjectContributionClasses.ModelElement()}),
                ResourceMapping.class,
                true
            );
        // Ensure that the case where an object uses a contribution adapter that doesn't handle mappings
        // will still show the menus for resource mappings
        assertPopupMenus("8", 
                new String[] {"ResourceMapping.1", "IResource.1"}, 
                new StructuredSelection(new Object[] {new ObjectContributionClasses.CResourceOnly()}),
                ResourceMapping.class,
                true
            );
    }
    
    /**
     * This tests adaptable contributions that are not IResource.
     * 
     * @since 3.1
     */
    public final void testAdaptables() throws CoreException {
    	assertPopupMenus("1", 
    			new String[] {"ICommon.1"}, 
    			new StructuredSelection(new Object[] {
    					new ObjectContributionClasses.A()}),
				ICommon.class,
				true
			);  
    	assertPopupMenus("2", 
    			new String[] {"ICommon.1"}, 
    			new StructuredSelection(new Object[] {
    					new ObjectContributionClasses.A(), 
						new ObjectContributionClasses.B()}),
				ICommon.class,
				true
			);      	
    	assertPopupMenus("3", 
    			new String[] {"ICommon.1"}, 
    			new StructuredSelection(new Object[] {
    					new ObjectContributionClasses.A(), 
						new ObjectContributionClasses.B(), 
						new ObjectContributionClasses.C(),
						new ObjectContributionClasses.Common()
				}),
				ICommon.class,
				true
			);
    	assertPopupMenus("4", 
    			new String[] {"ICommon.1"}, 
    			new StructuredSelection(new Object[] {
    					new ObjectContributionClasses.Common(), 
						new ObjectContributionClasses.C(), 
						new ObjectContributionClasses.B(),
						new ObjectContributionClasses.A()
				}),
				ICommon.class,
				true
			);
    	assertPopupMenus("5", 
    			new String[] {"ICommon.1"}, 
    			new StructuredSelection(new Object[] {
    					new ObjectContributionClasses.Common(), 
						new ObjectContributionClasses.C(), 
						new ObjectContributionClasses.B(),
						new ObjectContributionClasses.C(), 
						new ObjectContributionClasses.A(),
						new ObjectContributionClasses.Common() 
				}),
				ICommon.class,
				true
			);
    	assertPopupMenus("6", 
    			new String[] {"ICommon.1"}, 
    			new StructuredSelection(new Object[] { 
						new ObjectContributionClasses.C(),
						new ObjectContributionClasses.Common()
				}),
				ICommon.class,
				true
			);
    	assertPopupMenus("7", 
    			new String[] {"ICommon.1"}, 
    			new StructuredSelection(new Object[] { 
						new Object()				
				}),
				ICommon.class,
				false
			);
    	assertPopupMenus("8", 
    			new String[] {"ICommon.1"}, 
    			new StructuredSelection(new Object[] { 
    					new ObjectContributionClasses.C(),
						new Object()				
				}),
				ICommon.class,
				false
			);
    	assertPopupMenus("9", 
    			new String[] {"ICommon.1"}, 
    			new StructuredSelection(new Object[] { 
    					new ObjectContributionClasses.C(),
    					new ObjectContributionClasses.A(),
						new Object()				
				}),
				ICommon.class,
				false
			);
    }
    
    /**
     * Ensure that there are no duplicate contributions.
     * 
     * @since 3.1
     */
    public final void testDuplicateAdaptables() throws CoreException {
    	assertPopupMenus("1",
    			new String[] {"ICommon.1"}, 
    			new StructuredSelection(new Object[] {
    					new ObjectContributionClasses.D()}),
				ICommon.class,
				true
			);
    	// repeat test on purpose to ensure no double call duplicates.    	
    	assertPopupMenus("1",
    			new String[] {"ICommon.1"}, 
    			new StructuredSelection(new Object[] {
    					new ObjectContributionClasses.D()}),
				ICommon.class,
				true
			);
    	assertPopupMenus("2",
    			new String[] {"ICommon.1"}, 
    			new StructuredSelection(new Object[] {
    					new ObjectContributionClasses.D(),
						new ObjectContributionClasses.A()
						}),
				ICommon.class,
				true
			);
    	assertPopupMenus("3",
    			new String[] {"ICommon.1"}, 
    			new StructuredSelection(new Object[] {
    					new ObjectContributionClasses.A(),
						new ObjectContributionClasses.D()
						}),
				ICommon.class,
				true
			);
    	assertPopupMenus("4",
    			new String[] {"ICommon.1"}, 
    			new StructuredSelection(new Object[] {
    					new ObjectContributionClasses.Common(),
						new ObjectContributionClasses.D()
						}),
				ICommon.class,
				true
			);
    	assertPopupMenus("5",
    			new String[] {"ICommon.1"}, 
    			new StructuredSelection(new Object[] {    					
						new ObjectContributionClasses.D(),
						new ObjectContributionClasses.Common()
						}),
				ICommon.class,
				true
			);
    }
    
    /**
     * Test non-adaptable contributions
     * 
     * @since 3.1
     */
    public final void testNonAdaptableContributions() throws CoreException {
    	assertPopupMenus("1",
    			new String[] {"ICommon.2"}, 
    			new StructuredSelection(new Object[] {
    					new ObjectContributionClasses.A(),
						new ObjectContributionClasses.B()}),
				ICommon.class,
				false
			);
    	assertPopupMenus("2",
    			new String[] {"ICommon.2"}, 
    			new StructuredSelection(new Object[] {
    					new ObjectContributionClasses.D(),
						new ObjectContributionClasses.C(),
						new ObjectContributionClasses.Common()}),
				ICommon.class,
				true
			); 
    	assertPopupMenus("3",
    			new String[] {"Common.2"}, 
    			new StructuredSelection(new Object[] {
    					new ObjectContributionClasses.D(),
						new ObjectContributionClasses.C(),
						new ObjectContributionClasses.A()}),
				ICommon.class,
				false
			); 
    	assertPopupMenus("4",
    			new String[] {"Common.2"}, 
    			new StructuredSelection(new Object[] {
    					new ObjectContributionClasses.B(),
						new ObjectContributionClasses.C(),
						new ObjectContributionClasses.A()}),
				ICommon.class,
				false
			); 
    }
    
    /**
     * Helper class that will create a popup menu based on the given selection and
     * then ensure that the provided commandIds are added to the menu.
     * 
     * @param commandIds the command ids that should appear in the menu
     * @param selection the selection on which to contribute object contributions
     */
    public void assertPopupMenus(String name, String[] commandIds, final ISelection selection, Class selectionType, boolean existance) {
    	ISelectionProvider selectionProvider = new ISelectionProvider() {
			public void addSelectionChangedListener(ISelectionChangedListener listener) {
			}
			public ISelection getSelection() {
				return selection;
			}
			public void removeSelectionChangedListener(ISelectionChangedListener listener) {
			}
			public void setSelection(ISelection selection) {
			}
		};
		
		// The popup extender needs a part to notify actions of the active part
        final WorkbenchWindow window = (WorkbenchWindow) PlatformUI.getWorkbench().getActiveWorkbenchWindow();
        final IWorkbenchPage page = window.getActivePage();
        IWorkbenchPart part = page.getActivePartReference().getPart(true);
    	
    	 // Create a fake PopupMenuExtender so we can get some data back.
        final MenuManager fakeMenuManager = new MenuManager();
        fakeMenuManager.add(new GroupMarker(
                org.eclipse.ui.IWorkbenchActionConstants.MB_ADDITIONS));
        final PopupMenuExtender extender = new PopupMenuExtender(null,
                fakeMenuManager, selectionProvider, part);
        
        

        /*
         * Pretend to show the pop-up menu -- looking to motivate the extender
         * to fill the menu based on the selection provider.
         * 
         * TODO This causes a big delay (in the order of a minute or more) while
         * trying to fill this menu. It seems to be loading a bunch of plug-ins,
         * and doing class loading.
         */
        extender.menuAboutToShow(fakeMenuManager);

        extender.dispose();
        
        // Check to see if the appropriate object contributions are present.
        final IContributionItem[] items = fakeMenuManager.getItems();
        Set seenCommands = new HashSet(Arrays.asList(commandIds));
        List commands = new ArrayList(Arrays.asList(commandIds));
        for (int i = 0; i < items.length; i++) {
           IContributionItem contributionItem = items[i];
           // Step 1: test the selection
           if (selectionType != null) {
				IContributionItem item = contributionItem;
				if (item instanceof SubContributionItem) {
					item = ((SubContributionItem) contributionItem).getInnerItem();
				}
				if (item instanceof PluginActionContributionItem) {
					// Verify that the selection passed to the action has been
					// converted
					PluginActionContributionItem pa = (PluginActionContributionItem) item;
					ISelection s = null;
					if (s instanceof IStructuredSelection) {
						for (Iterator it = ((IStructuredSelection) s).iterator(); it.hasNext();) {
							Object element = (Object) it.next();
							assertTrue(name + " selection not converted", selectionType.isInstance(element));
						}
					}
				}
			}
           // Step 2: remember that we saw this element
           String id = contributionItem.getId();
           if(existance) {    		
           		boolean removed = commands.remove(id);	
           		if(seenCommands.contains(id) && ! removed) {
           			fail(name + " item duplicated in the context menu: " + id);
           		}           		
           } else {
           		assertTrue(name + " item should not be in the context menu", ! commands.contains(id));
           }
        }
        
        if(existance && ! commands.isEmpty()) {
        	fail(name + " Missing " + commands.toString() + " from context menu.");
        }
    }
}
