/*******************************************************************************
 * Copyright (c) 2010, 2019 SAP AG and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *    Mathias Kinzler (SAP AG) - initial implementation
 *    Tobias Baumann <tobbaumann@gmail.com> - Bug #494269
 *******************************************************************************/
package org.eclipse.egit.ui.view.repositories;

import static org.eclipse.swtbot.swt.finder.waits.Conditions.shellCloses;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasItem;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Adapters;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.egit.core.RepositoryUtil;
import org.eclipse.egit.core.op.StashCreateOperation;
import org.eclipse.egit.core.project.RepositoryMapping;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.JobFamilies;
import org.eclipse.egit.ui.UIPreferences;
import org.eclipse.egit.ui.common.StagingViewTester;
import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNode;
import org.eclipse.egit.ui.internal.repository.tree.StashedCommitNode;
import org.eclipse.egit.ui.test.ContextMenuHelper;
import org.eclipse.egit.ui.test.TestUtil;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
import org.eclipse.swtbot.swt.finder.utils.TableCollection;
import org.eclipse.swtbot.swt.finder.waits.Conditions;
import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotText;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.dialogs.WorkbenchWizardElement;
import org.eclipse.ui.internal.wizards.AbstractExtensionWizardRegistry;
import org.eclipse.ui.wizards.IWizardCategory;
import org.eclipse.ui.wizards.IWizardDescriptor;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

/**
 * SWTBot Tests for the Git Repositories View.
 *
 * <pre>
 * TODO
 * global copy and paste command
 * bare repository support including copy of path from workdir
 * copy path from file and folder
 * paste with empty and invalid path
 * create branch with selection not on a ref
 * tags altogether
 * fetch and push to configured remote
 * import wizard outside the "golden path"
 * </pre>
 */
@RunWith(SWTBotJunit4ClassRunner.class)
public class GitRepositoriesViewTest extends GitRepositoriesViewTestBase {

	private File repositoryFile;

	private boolean initialLinkingState;

	@Before
	public void prepare() throws Exception {
		setVerboseBranchMode(false);
		initialLinkingState = setLinkWithSelection(false);
		repositoryFile = createProjectAndCommitToRepository();
		RepositoryUtil.INSTANCE.addConfiguredRepository(repositoryFile);
	}

	@After
	public void resetLinkingState() {
		setLinkWithSelection(initialLinkingState);
	}

	/**
	 * First level should have 5 children
	 *
	 * @throws Exception
	 */
	@Test
	public void testExpandFirstLevel() throws Exception {
		SWTBotTree tree = getOrOpenView().bot().tree();
		SWTBotTreeItem item = TestUtil.expandAndWait(
				myRepoViewUtil.getRootItem(tree, repositoryFile));
		SWTBotTreeItem[] children = item.getItems();
		assertEquals("Wrong number of children", 5, children.length);
	}

	/**
	 * Tests that the tree does not suddenly have a node with a null repository.
	 *
	 * @throws Exception
	 * @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=552622">bug
	 *      552622</a>
	 */
	@Test
	public void testWithStagingView() throws Exception {
		// Fails consistently on Mac without the fix from bug 552622 and
		// succeeds with that fix. On Jenkins this test never failed?!
		SWTBotTree tree = getOrOpenView().bot().tree();
		StagingViewTester stagingViewTester = StagingViewTester
				.openStagingView();
		TestUtil.waitForDecorations();
		SWTBotTreeItem item = myRepoViewUtil.getRootItem(tree, repositoryFile);
		item.select();
		TestUtil.waitForDecorations();
		stagingViewTester.getView().close();
		TestUtil.waitForDecorations();
		SWTBotTreeItem[] items = tree.getAllItems();
		boolean[] hasNull = { false };
		String[] unknownClass = { "" };
		tree.widget.getDisplay().syncExec(() -> {
			for (SWTBotTreeItem i : items) {
				Object obj = i.widget.getData();
				if (!(obj instanceof RepositoryTreeNode)) {
					unknownClass[0] = obj.getClass().getName();
					break;
				}
				if (((RepositoryTreeNode) obj).getRepository() == null) {
					hasNull[0] = true;
					break;
				}
			}
		});
		assertEquals("Unknown tree element", "", unknownClass[0]);
		assertFalse("Tree has node with null repository", hasNull[0]);
	}

	/**
	 * Open (expand, file->editor, branch->checkout)
	 *
	 * @throws Exception
	 */
	@Test
	public void testOpen() throws Exception {
		// expand first level
		SWTBotTree tree = getOrOpenView().bot().tree();
		SWTBotTreeItem item = myRepoViewUtil.getRootItem(tree, repositoryFile);
		item.collapse();
		refreshAndWait();
		item = myRepoViewUtil.getRootItem(tree, repositoryFile);
		assertTrue("Item should not be expanded", !item.isExpanded());
		item.doubleClick();
		assertTrue("Item should be expanded", item.isExpanded());
		// open a file in editor
		item = TestUtil.expandAndWait(
				myRepoViewUtil.getWorkdirItem(tree, repositoryFile));
		SWTBotTreeItem fileiItem = TestUtil.expandAndWait(item.getNode(PROJ1))
				.getNode(FOLDER);
		fileiItem = TestUtil.expandAndWait(fileiItem).getNode(FILE1).select();
		fileiItem.doubleClick();
		assertTrue(bot.activeEditor().getTitle().equals(FILE1));
		bot.activeEditor().close();
		refreshAndWait();

		// opening current branch is a no-op
		String contentMaster = getTestFileContent();
		// open a branch (checkout)
		checkoutWithDoubleClick(tree, "stable");
		String contentStable = getTestFileContent();
		assertNotEquals("Content of master and stable should differ",
				contentMaster, contentStable);
	}

	private void checkoutWithDoubleClick(SWTBotTree tree, String branch)
			throws Exception {
		SWTBotTreeItem node = myRepoViewUtil.getLocalBranchesItem(tree,
				repositoryFile);
		TestUtil.expandAndWait(node).getNode(branch).doubleClick();
		SWTBotShell shell = bot
				.shell(UIText.RepositoriesView_CheckoutConfirmationTitle);
		shell.bot()
				.button(UIText.RepositoriesView_CheckoutConfirmationDefaultButtonLabel)
				.click();
		TestUtil.joinJobs(JobFamilies.CHECKOUT);
		refreshAndWait();
	}

	/**
	 * Checks for the Symbolic Reference node
	 *
	 * @throws Exception
	 */
	@Test
	public void testExpandSymbolicRef() throws Exception {
		SWTBotTree tree = getOrOpenView().bot().tree();
		SWTBotTreeItem item = TestUtil.expandAndWait(
				myRepoViewUtil.getSymbolicRefsItem(tree, repositoryFile));
		List<String> children = item.getNodes();
		boolean found = false;
		for (String child : children) {
			if (child.contains(Constants.HEAD)) {
				found = true;
				break;
			}
		}
		assertTrue(found);
	}

	/**
	 * Checks the first level of the working directory
	 *
	 * @throws Exception
	 */
	@Test
	public void testExpandWorkDir() throws Exception {
		SWTBotTree tree = getOrOpenView().bot().tree();
		Repository myRepository = lookupRepository(repositoryFile);
		List<String> children = Arrays
				.asList(myRepository.getWorkTree().list());
		List<String> treeChildren = TestUtil
				.expandAndWait(
						myRepoViewUtil.getWorkdirItem(tree, repositoryFile))
				.getNodes();
		assertTrue(children.containsAll(treeChildren)
				&& treeChildren.containsAll(children));
		SWTBotTreeItem item = TestUtil.expandAndWait(
				myRepoViewUtil.getWorkdirItem(tree, repositoryFile));
		item = TestUtil.expandAndWait(item.getNode(PROJ1));
		item = TestUtil.expandAndWait(item.getNode(FOLDER));
		item.getNode(FILE1);
	}

	/**
	 * Checks is some context menus are available, should be replaced with real
	 * tests
	 *
	 * @throws Exception
	 */
	@Test
	public void testContextMenuRepository() throws Exception {
		removeSmartImportWizardToForceGitImportWizardUsage();
		Activator.getDefault().getPreferenceStore()
				.setValue(UIPreferences.ALWAYS_USE_STAGING_VIEW, false);
		// We just check if the dialogs open, the actual commit and import
		// projects
		// is tested elsewhere
		SWTBotTree tree = getOrOpenView().bot().tree();
		SWTBotTreeItem item = myRepoViewUtil.getRootItem(tree, repositoryFile);
		item.select();
		assertClickOpens(tree,
				myUtil.getPluginLocalizedValue("RepoViewCommit.label"),
				UIText.CommitDialog_CommitChanges);
		assertClickOpens(tree,
				myUtil.getPluginLocalizedValue("RepoViewImportProjects.label"),
				NLS.bind(UIText.GitCreateProjectViaWizardWizard_WizardTitle,
						repositoryFile));
		Activator.getDefault().getPreferenceStore()
				.setValue(UIPreferences.ALWAYS_USE_STAGING_VIEW, true);
	}

	/**
	 * Show properties
	 *
	 * @throws Exception
	 */
	@Test
	public void testShowProperties() throws Exception {
		SWTBotTree tree = getOrOpenView().bot().tree();
		SWTBotTreeItem item = myRepoViewUtil.getRootItem(tree, repositoryFile);
		item.select();
		ContextMenuHelper.clickContextMenuSync(tree,
				myUtil.getPluginLocalizedValue("ShowIn"), "Properties");
		SWTBotView propertieView = bot.viewById(IPageLayout.ID_PROP_SHEET);
		assertTrue(propertieView.isActive());
	}

	/**
	 * Import wizard golden path test
	 *
	 * @throws Exception
	 */
	@Test
	public void testImportWizard() throws Exception {
		removeSmartImportWizardToForceGitImportWizardUsage();
		deleteAllProjects();
		assertProjectExistence(PROJ1, false);
		SWTBotTree tree = getOrOpenView().bot().tree();
		SWTBotTreeItem item = myRepoViewUtil.getRootItem(tree, repositoryFile);
		String wizardTitle = NLS.bind(
				UIText.GitCreateProjectViaWizardWizard_WizardTitle,
				repositoryFile.getPath());

		// start wizard from root item
		item.select();
		ContextMenuHelper.clickContextMenu(tree,
				myUtil.getPluginLocalizedValue("ImportProjectsCommand"));
		SWTBotShell shell = bot.shell(wizardTitle);
		bot.radio(UIText.GitSelectWizardPage_ImportExistingButton).click();
		TableCollection selected = shell.bot().tree().selection();
		String wizardNodeText = selected.get(0, 0);
		// wizard directory should be working dir
		String expected = myRepoViewUtil.getWorkdirItem(tree, repositoryFile)
				.getText();
		// One or the other or both or none might contain decorations
		assertTrue(expected.contains(wizardNodeText)
				|| wizardNodeText.contains(expected));
		shell.close();
		tree = getOrOpenView().bot().tree();
		// start wizard from .git
		TestUtil.expandAndWait(
				myRepoViewUtil.getWorkdirItem(tree, repositoryFile))
				.getNode(Constants.DOT_GIT).select();
		ContextMenuHelper.clickContextMenu(tree,
				myUtil.getPluginLocalizedValue("ImportProjectsCommand"));
		shell = bot.shell(wizardTitle);
		selected = shell.bot().tree().selection();
		wizardNodeText = selected.get(0, 0);
		// wizard directory should be .git
		assertEquals(Constants.DOT_GIT, wizardNodeText);
		shell.bot().button(IDialogConstants.NEXT_LABEL).click();
		shell.bot().label("Import Projects"); // wait for import projects page
		assertEquals(0, shell.bot().tree().getAllItems().length);
		shell.bot().button(IDialogConstants.BACK_LABEL).click();
		// go to project with .project
		shell.bot().tree().getAllItems()[0].getNode(PROJ1).select();
		// next is 1
		shell.bot().button(IDialogConstants.NEXT_LABEL).click();
		bot.button(UIText.WizardProjectsImportPage_deselectAll).click();
		assertEquals(1, shell.bot().tree().getAllItems().length);
		assertTrue(
				!shell.bot().button(IDialogConstants.FINISH_LABEL).isEnabled());
		shell.bot().button(UIText.WizardProjectsImportPage_selectAll).click();
		assertTrue(
				shell.bot().button(IDialogConstants.FINISH_LABEL).isEnabled());
		shell.bot().button(IDialogConstants.FINISH_LABEL).click();
		bot.waitUntil(Conditions.shellCloses(shell));
		assertProjectExistence(PROJ1, true);
		assertProjectIsShared(PROJ1, true);
	}

	private static void removeSmartImportWizardToForceGitImportWizardUsage()
			throws Exception {
		final String smartImportWizardId = "org.eclipse.e4.ui.importer.wizard";
		AbstractExtensionWizardRegistry wizardRegistry = (AbstractExtensionWizardRegistry) PlatformUI
				.getWorkbench().getImportWizardRegistry();
		IWizardCategory[] categories = PlatformUI.getWorkbench()
				.getImportWizardRegistry().getRootCategory().getCategories();
		for (IWizardDescriptor wizard : getAllWizards(categories)) {
			if (wizard.getId().equals(smartImportWizardId)) {
				WorkbenchWizardElement wizardElement = (WorkbenchWizardElement) wizard;
				wizardRegistry.removeExtension(
						wizardElement.getConfigurationElement()
								.getDeclaringExtension(),
						new Object[] { wizardElement });
				return;
			}
		}
	}

	private static IWizardDescriptor[] getAllWizards(
			IWizardCategory[] categories) {
		List<IWizardDescriptor> results = new ArrayList<>();
		for (IWizardCategory wizardCategory : categories) {
			results.addAll(Arrays.asList(wizardCategory.getWizards()));
			results.addAll(Arrays
					.asList(getAllWizards(wizardCategory.getCategories())));
		}
		return results.toArray(new IWizardDescriptor[0]);
	}

	@Test
	public void testImportWizardGeneralProject() throws Exception {
		removeSmartImportWizardToForceGitImportWizardUsage();
		deleteAllProjects();
		assertProjectExistence(PROJ2, false);
		SWTBotTree tree = getOrOpenView().bot().tree();
		String wizardTitle = NLS.bind(
				UIText.GitCreateProjectViaWizardWizard_WizardTitle,
				repositoryFile.getPath());
		// start wizard from PROJ2
		TestUtil.expandAndWait(
				myRepoViewUtil.getWorkdirItem(tree, repositoryFile))
				.getNode(PROJ2).select();
		ContextMenuHelper.clickContextMenu(tree,
				myUtil.getPluginLocalizedValue("ImportProjectsCommand"));
		SWTBotShell shell = bot.shell(wizardTitle);
		shell = bot.shell(wizardTitle);
		// try import existing project first
		bot.radio(UIText.GitSelectWizardPage_ImportExistingButton).click();
		TableCollection selected = shell.bot().tree().selection();
		String wizardNode = selected.get(0, 0);
		// wizard directory should be PROJ2
		assertEquals(PROJ2, wizardNode);
		shell.bot().button(IDialogConstants.NEXT_LABEL).click();
		assertWizardDialogMessage(shell.bot(),
				" " + UIText.GitProjectsImportPage_NoProjectsMessage);
		assertEquals(0, shell.bot().tree().getAllItems().length);
		shell.bot().button(IDialogConstants.BACK_LABEL).click();
		// import as general
		shell.bot().radio(UIText.GitSelectWizardPage_ImportAsGeneralButton)
				.click();
		shell.bot().button(IDialogConstants.NEXT_LABEL).click();
		assertEquals(PROJ2,
				shell.bot()
						.textWithLabel(
								UIText.GitCreateGeneralProjectPage_ProjectNameLabel)
						.getText());
		// switch to a sub directory and see if this is used
		shell.bot().button(IDialogConstants.BACK_LABEL).click();
		SWTBotTreeItem item = TestUtil
				.expandAndWait(shell.bot().tree().getAllItems()[0]);
		TestUtil.expandAndWait(item.getNode(PROJ2)).getNode(FOLDER).select();
		shell.bot().button(IDialogConstants.NEXT_LABEL).click();
		String name = shell.bot()
				.textWithLabel(
						UIText.GitCreateGeneralProjectPage_ProjectNameLabel)
				.getText();
		assertEquals(FOLDER, name);
		shell.bot().button(IDialogConstants.BACK_LABEL).click();
		// switch back to the root directory
		TestUtil.expandAndWait(shell.bot().tree().getAllItems()[0])
				.getNode(PROJ2).select();
		shell.bot().button(IDialogConstants.NEXT_LABEL).click();
		assertEquals(PROJ2,
				shell.bot()
						.textWithLabel(
								UIText.GitCreateGeneralProjectPage_ProjectNameLabel)
						.getText());

		shell.bot().button(IDialogConstants.FINISH_LABEL).click();
		bot.waitUntil(Conditions.shellCloses(shell));
		assertProjectExistence(PROJ2, true);
		assertProjectIsShared(PROJ2, true);
	}

	@Test
	public void testImportWizardGeneralProjectWithWorkingSet()
			throws Exception {
		removeSmartImportWizardToForceGitImportWizardUsage();
		deleteAllProjects();
		assertProjectExistence(PROJ1, false);
		String workingSetName = "myWorkingSet";
		removeWorkingSet(workingSetName);
		SWTBotTree tree = getOrOpenView().bot().tree();
		String wizardTitle = NLS.bind(
				UIText.GitCreateProjectViaWizardWizard_WizardTitle,
				repositoryFile.getPath());
		// start wizard from PROJ1
		TestUtil.expandAndWait(
				myRepoViewUtil.getWorkdirItem(tree, repositoryFile))
				.getNode(PROJ1).select();
		ContextMenuHelper.clickContextMenu(tree,
				myUtil.getPluginLocalizedValue("ImportProjectsCommand"));
		SWTBotShell shell = bot.shell(wizardTitle);
		shell = bot.shell(wizardTitle);
		// try import existing project first
		bot.radio(UIText.GitSelectWizardPage_ImportExistingButton).click();
		SWTBotButton button = shell.bot().button(IDialogConstants.NEXT_LABEL);
		// Set focus on the next button. If this is not done, Wizard Framework
		// restores
		// the focus to the "Import as &General Project" radio button. Setting
		// the focus on
		// the radio button selects the button and causes the test to fail.
		// See also SWTBot Bug 337465
		button.setFocus();
		button.click();
		assertWizardDialogMessage(shell.bot(),
				UIText.WizardProjectsImportPage_ImportProjectsDescription);
		shell.bot().tree().getAllItems()[0].check();
		// add to working set
		shell.bot().checkBox("Add project to working sets").select();
		// create new working set
		shell.bot().button("Select...").click();
		SWTBotShell workingSetDialog = bot.shell("Select Working Sets");
		workingSetDialog.bot().button("New...").click();
		SWTBotShell newDialog = bot.shell("New Working Set");
		newDialog.bot().table().select("Java");
		newDialog.bot().button(IDialogConstants.NEXT_LABEL).click();
		newDialog.bot().text(0).setText(workingSetName);
		newDialog.bot().button(IDialogConstants.FINISH_LABEL).click();
		workingSetDialog.bot().table().getTableItem(workingSetName).check();
		workingSetDialog.bot().button(IDialogConstants.OK_LABEL).click();
		shell.bot().button(IDialogConstants.FINISH_LABEL).click();
		bot.waitUntil(Conditions.shellCloses(shell));
		assertProjectExistence(PROJ1, true);
		assertProjectInWorkingSet(workingSetName, PROJ1);
		assertProjectIsShared(PROJ1, true);
		removeWorkingSet(workingSetName);
	}

	private void assertProjectInWorkingSet(String workingSetName,
			String projectName) {
		IWorkingSetManager workingSetManager = PlatformUI.getWorkbench()
				.getWorkingSetManager();
		IWorkingSet workingSet = workingSetManager
				.getWorkingSet(workingSetName);
		IAdaptable[] elements = workingSet.getElements();
		assertEquals("Wrong number of projects in working set", 1,
				elements.length);
		IProject project = Adapters.adapt(elements[0], IProject.class);
		assertEquals("Wrong project in working set", projectName,
				project.getName());
	}

	private void removeWorkingSet(String name) {
		IWorkingSetManager workingSetManager = PlatformUI.getWorkbench()
				.getWorkingSetManager();
		IWorkingSet workingSet = workingSetManager.getWorkingSet(name);
		if (workingSet != null)
			workingSetManager.removeWorkingSet(workingSet);
	}

	private void assertProjectIsShared(String projectName,
			boolean shouldBeShared) {
		IProject project = ResourcesPlugin.getWorkspace().getRoot()
				.getProject(projectName);
		RepositoryMapping mapping = RepositoryMapping.getMapping(project);
		if (shouldBeShared) {
			assertNotNull(mapping);
			assertNotNull(mapping.getRepository());
		} else
			assertNull(mapping);
	}

	@Test
	public void testLinkWithSelectionNavigator() throws Exception {
		deleteAllProjects();
		shareProjects(repositoryFile);
		SWTBotTree tree = getOrOpenView().bot().tree();
		myRepoViewUtil.getRootItem(tree, repositoryFile).select();
		// the selection should be root
		assertTrue(tree.selection().get(0, 0).contains(REPO1));

		SWTBotTree projectExplorerTree = TestUtil.getExplorerTree();
		getProjectItem(projectExplorerTree, PROJ1).select();

		// the selection should be still be root
		assertTrue(tree.selection().get(0, 0).contains(REPO1));

		// activate the link with selection
		toggleLinkWithSelection();

		// the selection should be project
		assertTrue(tree.selection().get(0, 0).equals(PROJ1));
	}

	/**
	 * Link with editor, both ways
	 *
	 * @throws Exception
	 */
	@Test
	public void testLinkWithSelectionEditor() throws Exception {
		deleteAllProjects();
		shareProjects(repositoryFile);
		SWTBotTree tree = getOrOpenView().bot().tree();
		myRepoViewUtil.getRootItem(tree, repositoryFile).select();
		// the selection should be root
		assertTrue(tree.selection().get(0, 0).startsWith(REPO1));

		SWTBotView view = TestUtil.showExplorerView();
		SWTBotTree projectExplorerTree = view.bot().tree();

		SWTBotTreeItem item = TestUtil
				.expandAndWait(getProjectItem(projectExplorerTree, PROJ1));
		item = TestUtil.expandAndWait(item.getNode(FOLDER)).getNode(FILE1);
		view.show();
		item.doubleClick();

		item = TestUtil
				.expandAndWait(getProjectItem(projectExplorerTree, PROJ1));
		item = TestUtil.expandAndWait(item.getNode(FOLDER)).getNode(FILE2);
		view.show();
		item.doubleClick();
		// now we should have two editors

		// the selection should be still be root
		assertTrue(tree.selection().get(0, 0).startsWith(REPO1));

		// activate the link with selection
		toggleLinkWithSelection();

		bot.editorByTitle(FILE2).show();
		// the selection should have changed to the latest editor
		TestUtil.waitUntilTreeHasSelectedNodeWithText(bot, tree, FILE2, 10000);

		bot.editorByTitle(FILE1).show();
		// selection should have changed
		TestUtil.waitUntilTreeHasSelectedNodeWithText(bot, tree, FILE1, 10000);

		// deactivate the link with editor
		toggleLinkWithSelection();

		bot.editorByTitle(FILE2).show();
		// the selection should be still be test.txt
		TestUtil.waitUntilTreeHasSelectedNodeWithText(bot, tree, FILE1, 10000);

		bot.editorByTitle(FILE1).show();

		item = TestUtil.expandAndWait(
				myRepoViewUtil.getWorkdirItem(tree, repositoryFile));
		item = TestUtil.expandAndWait(item.getNode(PROJ1));
		item = TestUtil.expandAndWait(item.getNode(FOLDER));
		item.getNode(FILE2).select();

		// the editor should still be test.txt
		assertEquals(FILE1, bot.activeEditor().getTitle());

		// activate again
		toggleLinkWithSelection();

		item = TestUtil.expandAndWait(
				myRepoViewUtil.getWorkdirItem(tree, repositoryFile));
		item = TestUtil.expandAndWait(item.getNode(PROJ1));
		item = TestUtil.expandAndWait(item.getNode(FOLDER));
		item.getNode(FILE2).select();
		TestUtil.waitUntilEditorIsActive(bot, bot.editorByTitle(FILE2), 10000);

		item = TestUtil.expandAndWait(
				myRepoViewUtil.getWorkdirItem(tree, repositoryFile));
		item = TestUtil.expandAndWait(item.getNode(PROJ1));
		item = TestUtil.expandAndWait(item.getNode(FOLDER));
		item.getNode(FILE1).select();
		TestUtil.waitUntilEditorIsActive(bot, bot.editorByTitle(FILE1), 10000);

		// deactivate the link with editor
		toggleLinkWithSelection();

		item = TestUtil.expandAndWait(
				myRepoViewUtil.getWorkdirItem(tree, repositoryFile));
		item = TestUtil.expandAndWait(item.getNode(PROJ1));
		item = TestUtil.expandAndWait(item.getNode(FOLDER));
		item.getNode(FILE2).select();
		TestUtil.waitUntilEditorIsActive(bot, bot.editorByTitle(FILE1), 10000);
	}

	@Test
	public void testDeleteSingleBranch() throws Exception {
		// expand first level
		SWTBotTree tree = getOrOpenView().bot().tree();
		refreshAndWait();
		// create a branch (no checkout)
		SWTBotTreeItem localBranchesItem = TestUtil.expandAndWait(
				myRepoViewUtil.getLocalBranchesItem(tree, repositoryFile));
		SWTBotTreeItem masterNode = localBranchesItem.getNode("master");
		masterNode.select();
		ContextMenuHelper.clickContextMenu(tree,
				myUtil.getPluginLocalizedValue("RepoViewCreateBranch.label"));
		SWTBotShell createBranchShell = bot
				.shell(UIText.CreateBranchWizard_NewBranchTitle);
		createBranchShell.bot().textWithId("BranchName").setText("abc");
		createBranchShell.bot().checkBox(UIText.CreateBranchPage_CheckoutButton)
				.deselect();
		createBranchShell.bot().button(IDialogConstants.FINISH_LABEL).click();
		bot.waitUntil(shellCloses(createBranchShell), 10000);
		refreshAndWait();
		// delete branch
		// lookup node again. Widget might have changed due to refresh
		localBranchesItem = TestUtil.expandAndWait(
				myRepoViewUtil.getLocalBranchesItem(tree, repositoryFile));
		localBranchesItem.getNode("abc").select();
		ContextMenuHelper.clickContextMenuSync(tree,
				myUtil.getPluginLocalizedValue("RepoViewDeleteBranch.label"));

		refreshAndWait();
		SWTBotTreeItem[] items = myRepoViewUtil
				.getLocalBranchesItem(tree, repositoryFile).getItems();
		assertEquals("Wrong number of branches", 2, items.length);
		assertEquals("master", items[0].getText());
		assertEquals("stable", items[1].getText());
	}

	@Test
	public void testDeleteBranchMultiple() throws Exception {
		// expand first level
		SWTBotTree tree = getOrOpenView().bot().tree();
		refreshAndWait();
		// open a branch (checkout)
		SWTBotTreeItem localBranchesItem = TestUtil.expandAndWait(
				myRepoViewUtil.getLocalBranchesItem(tree, repositoryFile));
		SWTBotTreeItem masterNode = localBranchesItem.getNode("master");
		// create first branch (abc)
		masterNode.select();
		ContextMenuHelper.clickContextMenu(tree, "Create Branch...");
		SWTBotShell createBranchShell = bot
				.shell(UIText.CreateBranchWizard_NewBranchTitle);
		createBranchShell.bot().textWithId("BranchName").setText("abc");
		createBranchShell.bot().checkBox(UIText.CreateBranchPage_CheckoutButton)
				.deselect();
		createBranchShell.bot().button(IDialogConstants.FINISH_LABEL).click();
		bot.waitUntil(shellCloses(createBranchShell), 10000);
		refreshAndWait();
		// create second branch (123)
		ContextMenuHelper.clickContextMenu(tree, "Create Branch...");
		createBranchShell = bot.shell(UIText.CreateBranchWizard_NewBranchTitle);
		SWTBotText bn = createBranchShell.bot().textWithId("BranchName");
		bn.setText("123");
		createBranchShell.bot().checkBox(UIText.CreateBranchPage_CheckoutButton)
				.deselect();
		createBranchShell.bot().button(IDialogConstants.FINISH_LABEL).click();
		bot.waitUntil(shellCloses(createBranchShell), 10000);
		refreshAndWait();
		localBranchesItem = TestUtil.expandAndWait(
				myRepoViewUtil.getLocalBranchesItem(tree, repositoryFile));
		// delete both
		localBranchesItem.select("abc", "123");
		ContextMenuHelper.clickContextMenuSync(tree,
				myUtil.getPluginLocalizedValue("RepoViewDeleteBranch.label"));
		refreshAndWait();

		SWTBotTreeItem[] items = myRepoViewUtil
				.getLocalBranchesItem(tree, repositoryFile).getItems();
		assertEquals("Wrong number of branches", 2, items.length);
		assertEquals("master", items[0].getText());
		assertEquals("stable", items[1].getText());
	}

	@Test
	public void testDeleteFileInProject() throws Exception {
		SWTBotTree tree = getOrOpenView().bot().tree();
		refreshAndWait();

		IProject project1 = ResourcesPlugin.getWorkspace().getRoot()
				.getProject(PROJ1);
		// Make sure that the refresh doesn't happen on delete and cause a
		// timeout
		project1.refreshLocal(IResource.DEPTH_INFINITE, null);

		SWTBotTreeItem folder = findWorkdirNode(tree, PROJ1, FOLDER);
		folder.getNode(FILE1).select();

		ContextMenuHelper.clickContextMenu(tree,
				myUtil.getPluginLocalizedValue("RepoViewDeleteFile.label"));

		SWTBotShell confirm = bot.shell("Delete Resources");
		confirm.bot().button(IDialogConstants.OK_LABEL).click();
		bot.waitUntil(shellCloses(confirm));
		TestUtil.joinJobs(JobFamilies.REPO_VIEW_REFRESH);

		folder = findWorkdirNode(tree, PROJ1, FOLDER);
		assertThat(folder.getNodes(), not(hasItem(FILE1)));
		assertThat(folder.getNodes(), hasItem(FILE2));
	}

	@Test
	public void testDeleteFileNotInProject() throws Exception {
		// PROJ2 is still a valid Eclipse project at that point, even though the
		// .project file wasn't committed. Close it.
		ResourcesPlugin.getWorkspace().getRoot().getProject(PROJ2).close(null);
		SWTBotTree tree = getOrOpenView().bot().tree();
		refreshAndWait();

		SWTBotTreeItem folder = findWorkdirNode(tree, PROJ2, FOLDER);
		int n = folder.getNodes().size();
		folder.getNode(FILE1).select();

		ContextMenuHelper.clickContextMenu(tree,
				myUtil.getPluginLocalizedValue("RepoViewDeleteFile.label"));

		SWTBotShell confirm = bot
				.shell(UIText.DeletePathsOperationUI_confirmActionTitle);
		confirm.bot().button(UIText.DeletePathsOperationUI_ButtonOK).click();
		bot.waitUntil(shellCloses(confirm));
		bot.waitUntil(new DefaultCondition() {

			@Override
			public boolean test() throws Exception {
				SWTBotTreeItem item = findWorkdirNode(tree, PROJ2, FOLDER);
				return item.getNodes().size() == n - 1;
			}

			@Override
			public String getFailureMessage() {
				return "File deletion not reflected in repo view tree within timout";
			}
		}, 20000);
		folder = findWorkdirNode(tree, PROJ2, FOLDER);
		assertThat(folder.getNodes(), not(hasItem(FILE1)));
		assertThat(folder.getNodes(), hasItem(FILE2));
	}

	@Test
	public void testStashDeleteCreate() throws Exception {
		Repository repo = lookupRepository(repositoryFile);
		IFile file = touch("Something");
		new StashCreateOperation(repo, "First stash").execute(null);
		file.refreshLocal(IResource.DEPTH_ZERO, null);
		touch("Something else");
		new StashCreateOperation(repo, "Second stash").execute(null);
		file.refreshLocal(IResource.DEPTH_ZERO, null);
		touch("Something else again");
		new StashCreateOperation(repo, "Third stash").execute(null);
		file.refreshLocal(IResource.DEPTH_ZERO, null);
		SWTBotTree tree = getOrOpenView().bot().tree();
		refreshAndWait();

		SWTBotTreeItem item = myRepoViewUtil.getStashesItem(tree,
				repositoryFile);
		item = TestUtil.expandAndWait(item);
		assertEquals("Unexpected number of stashed commits", 3,
				item.getItems().length);
		item.getNode(0).select();
		ContextMenuHelper.clickContextMenu(tree,
				myUtil.getPluginLocalizedValue("StashDropCommand.label"));
		SWTBotShell confirm = bot.shell(UIText.StashDropCommand_confirmTitle);
		confirm.bot().button(UIText.StashDropCommand_buttonDelete).click();
		bot.waitUntil(shellCloses(confirm));
		TestUtil.joinJobs(JobFamilies.STASH);
		TestUtil.joinJobs(JobFamilies.REPO_VIEW_REFRESH);
		touch("Something different");
		tree.getAllItems()[0].select();
		ContextMenuHelper.clickContextMenu(tree,
				myUtil.getPluginLocalizedValue("StashesMenu.label"),
				UIText.StashesMenu_StashChangesActionText);
		confirm = bot.shell(UIText.StashCreateCommand_titleEnterCommitMessage);
		confirm.bot().button(UIText.StashCreateCommand_ButtonOK).click();
		bot.waitUntil(shellCloses(confirm));
		TestUtil.joinJobs(JobFamilies.STASH);
		TestUtil.joinJobs(JobFamilies.REPO_VIEW_REFRESH);
		item = myRepoViewUtil.getStashesItem(tree, repositoryFile);
		assertStashes(item.getItems(), 3);
	}

	@Test
	public void testStashDeleteMultiple() throws Exception {
		Repository repo = lookupRepository(repositoryFile);
		IFile file = touch("Something");
		new StashCreateOperation(repo, "First stash").execute(null);
		file.refreshLocal(IResource.DEPTH_ZERO, null);
		touch("Something else");
		new StashCreateOperation(repo, "Second stash").execute(null);
		file.refreshLocal(IResource.DEPTH_ZERO, null);
		touch("Something else again");
		new StashCreateOperation(repo, "Third stash").execute(null);
		file.refreshLocal(IResource.DEPTH_ZERO, null);
		SWTBotTree tree = getOrOpenView().bot().tree();
		refreshAndWait();

		SWTBotTreeItem item = myRepoViewUtil.getStashesItem(tree,
				repositoryFile);
		item = TestUtil.expandAndWait(item);
		assertEquals("Unexpected number of stashed commits", 3,
				item.getItems().length);
		item.select(1, 2);
		ContextMenuHelper.clickContextMenu(tree,
				myUtil.getPluginLocalizedValue("StashDropCommand.label"));
		SWTBotShell confirm = bot.shell(UIText.StashDropCommand_confirmTitle);
		confirm.bot().button(UIText.StashDropCommand_buttonDelete).click();
		bot.waitUntil(shellCloses(confirm));
		TestUtil.joinJobs(JobFamilies.STASH);
		TestUtil.joinJobs(JobFamilies.REPO_VIEW_REFRESH);
		item = myRepoViewUtil.getStashesItem(tree, repositoryFile);
		assertStashes(item.getItems(), 1, "Third stash");
	}

	private void assertStashes(SWTBotTreeItem[] children, int expectedSize,
			String... decorations)
			throws Exception {
		assertEquals("Expected " + expectedSize + " children", expectedSize,
				children.length);
		if (decorations != null && decorations.length > 0) {
			TestUtil.waitForDecorations();
		}
		int[] indices = new int[expectedSize];
		int[] expectedIndices = new int[expectedSize];
		for (int i = 0; i < indices.length; i++) {
			indices[i] = -1;
			expectedIndices[i] = i;
		}
		children[0].display.syncExec(() -> {
			int j = 0;
			for (SWTBotTreeItem child : children) {
				Object data = child.widget.getData();
				if (data instanceof StashedCommitNode) {
					indices[j++] = ((StashedCommitNode) data).getIndex();
				}
			}
		});
		assertArrayEquals("Unexpected stash indices", expectedIndices, indices);
		for (int i = 0; i < children.length; i++) {
			String text = children[i].getText();
			assertTrue("Stash " + i + " has wrong label: " + text,
					text.startsWith("stash@{" + i + "}"));
			if (decorations != null && i < decorations.length) {
				String deco = decorations[i];
				if (deco != null) {
					assertTrue("Label should contain '" + deco + "': " + text,
							text.contains(deco));
				}
			}
		}
	}

	private void toggleLinkWithSelection() throws Exception {
		getOrOpenView().toolbarButton(
				myUtil.getPluginLocalizedValue(
						"RepoViewLinkWithSelection.tooltip"))
				.click();
	}

	private SWTBotTreeItem findWorkdirNode(SWTBotTree tree, String... nodes)
			throws Exception {
		SWTBotTreeItem item = myRepoViewUtil.getWorkdirItem(tree,
				repositoryFile);
		for (String node : nodes) {
			item = TestUtil.expandAndWait(item).getNode(node);
		}
		return item.expand();
	}
}
