package org.eclipse.platform.discovery.ui.test.comp.internal.pageobjects;

import static org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable.syncExec;

import java.text.MessageFormat;
import java.util.Collection;
import java.util.LinkedList;

import junit.framework.Assert;

import org.eclipse.platform.discovery.core.api.ISearchContext;
import org.eclipse.platform.discovery.core.api.SearchEvent;
import org.eclipse.platform.discovery.core.internal.IDestinationsManager;
import org.eclipse.platform.discovery.core.internal.ISearchSession;
import org.eclipse.platform.discovery.core.internal.SearchConsoleController;
import org.eclipse.platform.discovery.core.internal.console.ISearchConsoleControllerOutputView;
import org.eclipse.platform.discovery.core.internal.events.handlers.ISearchEventHandler;
import org.eclipse.platform.discovery.runtime.api.SearchFailedException;
import org.eclipse.platform.discovery.runtime.internal.ISearchProviderConfiguration;
import org.eclipse.platform.discovery.runtime.internal.ProviderNotFoundException;
import org.eclipse.platform.discovery.testutils.utils.pageobjects.InShellPageObject;
import org.eclipse.platform.discovery.ui.api.IGenericViewCustomization;
import org.eclipse.platform.discovery.ui.api.IViewUiContext;
import org.eclipse.platform.discovery.ui.api.impl.DefaultSessionIds;
import org.eclipse.platform.discovery.ui.internal.plugin.DiscoveryUIMessages;
import org.eclipse.platform.discovery.ui.internal.search.advancedparams.IAdvancedSearchParamsDisplayer;
import org.eclipse.platform.discovery.ui.internal.view.ISearchProviderSelector;
import org.eclipse.platform.discovery.ui.internal.view.SearchConsoleView;
import org.eclipse.platform.discovery.ui.internal.view.impl.ITabbedSessionDisplayer;
import org.eclipse.platform.discovery.ui.test.comp.internal.pageobjects.swtbot.SWTBotHyperlink;
import org.eclipse.platform.discovery.ui.test.comp.internal.pageobjects.swtbot.SWTBotTextWithMessage;
import org.eclipse.platform.discovery.ui.test.comp.internal.pageobjects.swtbot.SwtBotUtils;
import org.eclipse.platform.discovery.util.api.env.IDiscoveryEnvironment;
import org.eclipse.platform.discovery.util.internal.session.ISessionManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
import org.eclipse.swtbot.swt.finder.results.VoidResult;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotCombo;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotLabel;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Hyperlink;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;

public class SearchConsolePageObject extends InShellPageObject
{

	@Mock
	private IWorkbenchPartSite viewSite;
	
	@Mock
	private IDestinationsManager destManager;


	private final ISearchProviderConfiguration searchProviderConfiguration;
	private final ITabbedSessionDisplayer<ISearchContext> sessionDisplayer;
	private final IAdvancedSearchParamsDisplayer advancedParamsDisplayer;
	private final IDiscoveryEnvironment env;
	private final IViewUiContext uiContext;
	private final SwtBotUtils botUtils;

	private PageObjectConsoleView consoleView;
	private PageObjectController viewController;

	public SearchConsolePageObject(final ISearchProviderConfiguration searchProviderConfiguration, final ITabbedSessionDisplayer<ISearchContext> sessionDisplayer, final IAdvancedSearchParamsDisplayer advancedParamsDisplayer, final IDiscoveryEnvironment environment, final IViewUiContext uiContext)
	{
		MockitoAnnotations.initMocks(this);
		this.searchProviderConfiguration = searchProviderConfiguration;
		this.sessionDisplayer = sessionDisplayer;
		this.advancedParamsDisplayer = advancedParamsDisplayer;
		this.env = environment;
		this.uiContext = uiContext;
		this.botUtils = new SwtBotUtils();
	}

	@Override
	protected Shell createShell()
	{
		final Shell shell = super.createShell();
		Mockito.stub(viewSite.getShell()).toReturn(shell);
		return shell;
	}

	@Override
	protected void createContent(final Shell parent, final FormToolkit formToolkit)
	{
		syncExec(new VoidResult()
		{
			@Override
			public void run()
			{
				parent.setLayout(new FillLayout(SWT.VERTICAL));
				consoleView = new PageObjectConsoleView();
				
				consoleView.setEnvironment(env);
				consoleView.setUiContext(uiContext);
				consoleView.createPartControl(parent);
			}
		});
	}

	@Override
	public void open()
	{
		super.open();
		syncExec(new VoidResult()
		{

			@Override
			public void run()
			{
				shell().widget.layout();
				consoleView.setDefaultSessionId(DefaultSessionIds.mainSearchSessionId);
				consoleView.setEnvironment(env);
				viewController = new PageObjectController(searchProviderConfiguration, consoleView, env, null, DefaultSessionIds.mainSearchSessionId);
				consoleView.registerController(viewController);
				consoleView.setDestinationsManager(destManager);
				consoleView.initializationCompleted();
			}
		});
	}

	public IWorkbenchPartSite getViewSiteMock()
	{
		return this.viewSite;
	}

	public String getSelectedObject()
	{
		final SWTBotCombo objectsCombo = findObjectTypesCombo();
		return (objectsCombo.selectionIndex() == -1) ? null : objectsCombo.selection();
	}

	public void selectObject(final String objectName)
	{
		findObjectTypesCombo().setSelection(objectName);
	}

	public Collection<String> getCategories()
	{
		final Collection<String> categories = new LinkedList<String>();
		for (SWTBotTreeItem item : getAllCategoryItems())
		{
			categories.add(item.getText());
		}

		return categories;
	}

	public void verifyManageDestinationsWorksCorrectly()
	{
		final SWTBotHyperlink manageDestinationsLink = new SWTBotHyperlink(botUtils.findOneChildControlOfExactType(shell().widget, Hyperlink.class, true));
		manageDestinationsLink.click();

		Mockito.verify(destManager).manageDestinations(Mockito.same(shell().widget), Mockito.same(consoleView.getSearchProviderSelector().getActiveDestinationCategory()));
		
	}
    public void verifySearchPerformed(final String objectTypeId, final String destinationName, final String keyword)
	{
		Assert.assertNotNull("Search was not invoked", viewController.lastSearchEvent);
		Assert.assertEquals("Unexpected object id", objectTypeId, viewController.lastSearchEvent.getSearchParameters().getObjectTypeId());
		Assert.assertEquals("Unexpected destination", destinationName, viewController.lastSearchEvent.getSearchParameters().getSearchDestination().getDisplayName());
		Assert.assertEquals("Unexpected keyword", keyword, viewController.lastSearchEvent.getSearchParameters().getKeywordString());
	}

	private SWTBotTreeItem getCategoryItem(final String categoryName)
	{
		for (SWTBotTreeItem categoryItem : getAllCategoryItems())
		{
			if (categoryItem.getText().equals(categoryName))
			{
				return categoryItem;
			}
		}
		throw new WidgetNotFoundException(MessageFormat.format("Category {0} not found", categoryName));
	}

	private SWTBotTree findDestinationsTree()
	{
		return new SWTBotTree(findSiblingByLabel(DiscoveryUIMessages.SEARCH_IN_LIST_VIEWER_LABEL, Tree.class));
	}

	private SWTBotTreeItem[] getAllCategoryItems()
	{
		return findDestinationsTree().getAllItems();
	}

	private SWTBotCombo findObjectTypesCombo()
	{
		return new SWTBotCombo(findSiblingByLabel(DiscoveryUIMessages.SEARCH_FOR_LIST_VIEWER_LABEL, Combo.class));
	}

	private <T extends Widget> T findSiblingByLabel(final String labelText, final Class<T> targetClass)
	{
		return botUtils.findSibling(bot().label(labelText), targetClass);
	}

	public void selectDestination(final String categoryName, final String destinationName)
	{
		findDestination(categoryName, destinationName).select();
	}

	public boolean isDestinationVisible(final String categoryName, final String destinationName)
	{
		try
		{
			findDestination(categoryName, destinationName);
			return true;
		}
		catch (WidgetNotFoundException e)
		{
			return false;
		}
	}

	public Collection<String> getDestinationsForCategory(final String categoryName)
	{
		final Collection<String> result = new LinkedList<String>();
		for (SWTBotTreeItem destinationItem : getCategoryItem(categoryName).getItems())
		{
			result.add(destinationItem.getText());
		}

		return result;
	}

	public void expandDestinations()
	{
		for (SWTBotTreeItem categoryItem : getAllCategoryItems())
		{
			categoryItem.expand();
		}
	}

	public boolean canSelectHierarchy()
	{
		return findGroupingHierarchyCombo().isEnabled();
	}

	public String getSelectedGroupingHierarchy()
	{
		return findGroupingHierarchyCombo().getText();
	}

	public String getKeyword()
	{
		final SWTBotTextWithMessage keywordText = findKeywordText();
		// The logic below reflects the org.eclipse.platform.discovery.ui.internal.view.impl.TextControl implementation details
		if(!keywordText.isEnabled())
		{
			return keywordText.getText();
		}
		if(keywordText.getText().length() == 0)
		{
			return keywordText.getMessage();
		}
		return keywordText.getText();
	}

	public void enterKeyword(final String keyword)
	{
		if (!canEnterSearchText())
		{
			throw new IllegalStateException("Cannot enter keyword as the text is disabled");
		}
		findKeywordText().setText(keyword);
	}

	public void selectFirstPossibleDestination()
	{
		expandDestinations();
		getAllCategoryItems()[0].getItems()[0].select();
	}

	public void search()
	{
		if (!canSearch())
		{
			throw new IllegalStateException("Search is not possible now as the search button is disabled");
		}
		findSearchButton().click();
	}

	public void registerViewCustomization(final IGenericViewCustomization... customizations)
	{
		for (IGenericViewCustomization cust : customizations)
		{
			consoleView.registerViewCustomization(cust);
		}
	}

	public void showResult(final ISearchContext searchContext)
	{
		syncExec(new VoidResult()
		{
			@Override
			public void run()
			{
				consoleView.showResult(searchContext);
			}
		});
	}

	public boolean canSelectObject()
	{
		return findObjectTypesCombo().isEnabled();
	}

	public boolean canSelectDestination()
	{
		return findDestinationsTree().isEnabled();
	}

	public boolean canEnterSearchText()
	{
		return findKeywordText().isEnabled();
	}

	public boolean canSelectSubdestination()
	{
		return findSubdestinationsSelectorButton().isEnabled();
	}

	public boolean canSearch()
	{
		return findSearchButton().isEnabled();
	}

	private SWTBotTreeItem findDestination(final String categoryName, final String destinationName)
	{
		for (SWTBotTreeItem categoryItem : getAllCategoryItems())
		{
			if (!categoryItem.getText().equals(categoryName))
			{
				continue;
			}

			try
			{
				return categoryItem.getNode(destinationName);
			}
			catch (WidgetNotFoundException e)
			{
				throw new WidgetNotFoundException(MessageFormat.format("Coulkd find destination {0} for category {1}", destinationName, categoryName), e);
			}
		}
		throw new WidgetNotFoundException(MessageFormat.format("Could find category {0}", categoryName));
	}

	private SWTBotTextWithMessage findKeywordText()
	{
		return new SWTBotTextWithMessage(findSiblingByLabel(DiscoveryUIMessages.SEARCH_KEYWORD_LABEL, Text.class));
	}

	private SWTBotLabel findSubdestinationsSelectorButton()
	{
		return new SWTBotLabel(findSiblingByLabel(DiscoveryUIMessages.SEARCH_KEYWORD_LABEL, Label.class));
	}

	private SWTBotButton findSearchButton()
	{
		return bot().button(DiscoveryUIMessages.SEARCH_BUTTON_LABEL);
	}

	private SWTBotCombo findGroupingHierarchyCombo()
	{
		return new SWTBotCombo(findSiblingByLabel(DiscoveryUIMessages.GROUP_BY_LABEL, Combo.class));
	}

	private class PageObjectConsoleView extends SearchConsoleView
	{
		protected ISearchProviderConfiguration getSearchProviderConfiguration()
		{
			return searchProviderConfiguration;
		};

		@Override
		protected ITabbedSessionDisplayer<ISearchContext> createSessionsDisplayer()
		{
			return sessionDisplayer;
		}

		@Override
		public IWorkbenchPartSite getSite()
		{
			return viewSite;
		}

		@Override
		protected IAdvancedSearchParamsDisplayer createAdvancedSearchParamsDisplayer(Composite parent, FormToolkit formToolkit)
		{
			return advancedParamsDisplayer;
		}
		
		protected ISearchProviderSelector getSearchProviderSelector() {
			return searchProviderSelector;
		}
	}

	private class PageObjectController extends SearchConsoleController
	{
		public SearchEvent lastSearchEvent;

		public PageObjectController(ISearchProviderConfiguration providerConfiguration, ISearchConsoleControllerOutputView searchConsoleView, IDiscoveryEnvironment consoleEnv, ISessionManager<ISearchSession> sessionManager, String defaultSessionId)
		{
			super(providerConfiguration, searchConsoleView, consoleEnv, sessionManager, defaultSessionId);
		}

		@Override
		protected ISearchEventHandler createSearchEventHandler()
		{
			return new ISearchEventHandler()
			{
				@Override
				public void handleSearch(SearchEvent event) throws ProviderNotFoundException, SearchFailedException
				{
					lastSearchEvent = event;
				}
			};
		}
	}
}
