/*******************************************************************************
 * Copyright (c) 2011 SAP AG, Walldorf
 * 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:
 *    SAP AG - initial API and implementation
 *******************************************************************************/
package org.eclipse.platform.discovery.testutils.utils.registry;

import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.platform.discovery.destprefs.api.ISearchDestinationConfigurator;
import org.eclipse.platform.discovery.destprefs.internal.xpparser.SearchDestinationsConfiguratorXPParser;
import org.eclipse.platform.discovery.runtime.api.IDestinationsProvider;
import org.eclipse.platform.discovery.runtime.api.ISearchDestination;
import org.eclipse.platform.discovery.runtime.api.ISearchProvider;
import org.eclipse.platform.discovery.runtime.api.persistence.IMementoLoadProvider;
import org.eclipse.platform.discovery.runtime.api.persistence.IMementoStoreProvider;
import org.eclipse.platform.discovery.runtime.internal.persistence.xp.MementoLoadProvidersExtensionParser;
import org.eclipse.platform.discovery.runtime.internal.persistence.xp.MementoStoreProvidersExtensionParser;
import org.eclipse.platform.discovery.runtime.internal.xp.impl.DestinationsCategoryExtensionParser;
import org.eclipse.platform.discovery.runtime.internal.xp.impl.DestinationsProviderExtensionParser;
import org.eclipse.platform.discovery.runtime.internal.xp.impl.ObjectTypeExtensionParser;
import org.eclipse.platform.discovery.runtime.internal.xp.impl.SearchProvidersExtensionParser;
import org.eclipse.platform.discovery.runtime.internal.xp.impl.SearchSubdestinationExtensionParser;
import org.eclipse.platform.discovery.ui.api.IAdvancedSearchParamsUiContributor;
import org.eclipse.platform.discovery.ui.api.ISearchResultCustomUiCreator;
import org.eclipse.platform.discovery.ui.internal.xp.impl.AdvancedSearchParamsUiContribXpParser;
import org.eclipse.platform.discovery.ui.internal.xp.impl.CustomResultUiXpParser;
import org.eclipse.platform.discovery.util.internal.StatusUtils;
import org.osgi.framework.FrameworkUtil;
public class ExtensionRegistryBuilder {

	private IExtensionRegistry extensionRegistry;

	private IExtensionPoint objectTypesExtensionPoint;
	private IExtensionPoint destinationProvidersExtensionPoint;
	private IExtensionPoint destinationCategoriesExtensionPoint;
	private IExtensionPoint loadProvidersExtensionPoint;
	private IExtensionPoint storeProvidersExtensionPoint;
	private IExtensionPoint searchProvidersExtensionPoint;
	private IExtensionPoint searchSubdestinationsExtensionPoint;
	private IExtensionPoint advancedSearchUiContributorsExtensionPoint;
	private IExtensionPoint customResultUiContributorsExtensionPoint;
	private IExtensionPoint searchDestinationsConfiguratorExtensionPoint;

	private List<IConfigurationElement> objectTypes = new ArrayList<IConfigurationElement>();
	private List<IConfigurationElement> destinationProviders = new ArrayList<IConfigurationElement>();
	private List<IConfigurationElement> destinationCategories = new ArrayList<IConfigurationElement>();
	private List<IConfigurationElement> loadProviders = new ArrayList<IConfigurationElement>();
	private List<IConfigurationElement> storeProviders = new ArrayList<IConfigurationElement>();
	private List<IConfigurationElement> searchProviders = new ArrayList<IConfigurationElement>();
	private List<IConfigurationElement> searchSubdestinations = new ArrayList<IConfigurationElement>();
	private List<IConfigurationElement> advancedSearchUiContributors = new ArrayList<IConfigurationElement>();
	private List<IConfigurationElement> customResultUiContributors = new ArrayList<IConfigurationElement>();
	private List<IConfigurationElement> searchDestinationConfigurators = new ArrayList<IConfigurationElement>();


	public ExtensionRegistryBuilder() {

		this.extensionRegistry = mock(IExtensionRegistry.class, "extension registry");
		objectTypesExtensionPoint = setupExtensionPoint(ObjectTypeExtensionParser.XP_ID);
		destinationProvidersExtensionPoint = setupExtensionPoint(DestinationsProviderExtensionParser.XP_ID);
		destinationCategoriesExtensionPoint = setupExtensionPoint(DestinationsCategoryExtensionParser.XP_ID);
		loadProvidersExtensionPoint = setupExtensionPoint(MementoLoadProvidersExtensionParser.XP_ID);
		storeProvidersExtensionPoint = setupExtensionPoint(MementoStoreProvidersExtensionParser.XP_ID);
		searchProvidersExtensionPoint = setupExtensionPoint(SearchProvidersExtensionParser.XP_ID);
		searchSubdestinationsExtensionPoint = setupExtensionPoint(SearchSubdestinationExtensionParser.XP_ID);
		advancedSearchUiContributorsExtensionPoint = setupExtensionPoint(AdvancedSearchParamsUiContribXpParser.XP_ID);
		customResultUiContributorsExtensionPoint = setupExtensionPoint(CustomResultUiXpParser.XP_ID);
		searchDestinationsConfiguratorExtensionPoint = setupExtensionPoint(SearchDestinationsConfiguratorXPParser.XP_ID);
	}

	protected IExtensionPoint setupExtensionPoint(String xpId) {
		IExtensionPoint point = mock(IExtensionPoint.class, "extension point for" + xpId);
		when(extensionRegistry.getExtensionPoint(eq(xpId))).thenReturn(point);
		return point;
	}

	public void addObjectType(String id, String displayName) {
		IConfigurationElement element = createConfigurationElement(ObjectTypeExtensionParser.XP_ELEMENT_NAME);
		setAttribute(element, ObjectTypeExtensionParser.ID_ATTR_NAME, id);
		setAttribute(element, ObjectTypeExtensionParser.DISPLAY_NAME_ATTR_NAME, displayName);
		objectTypes.add(element);
	}

	public void addDestinationsProvider(String providerId, String destinationCategory, String preferencePageId, String providerInstanceFqName, IDestinationsProvider providerInstance) {
		IConfigurationElement element = createConfigurationElement(DestinationsProviderExtensionParser.XP_ELEMENT_NAME);
		setAttribute(element, DestinationsProviderExtensionParser.PROVIDER_ID_ATTR, providerId);
		setAttribute(element, DestinationsProviderExtensionParser.DEST_CATEGORY_ATTR, destinationCategory);
		setAttribute(element, DestinationsProviderExtensionParser.PROVIDER_PREF_PAGE_ID, preferencePageId);
		setAttribute(element, DestinationsProviderExtensionParser.PROVIDER_INSTANCE_ATTR, providerInstanceFqName);
		setExecutableExtension(element, providerInstance, DestinationsProviderExtensionParser.PROVIDER_INSTANCE_ATTR);
		destinationProviders.add(element);
	}

	protected void setExecutableExtension(IConfigurationElement element, Object objectToReturn, String classAttributeName) {
		try {
			when(element.createExecutableExtension(classAttributeName)).thenReturn(objectToReturn);
		} catch (CoreException e) {
			throw new RuntimeException(e);
		}
	}

	protected void setAttribute(IConfigurationElement element, String attributeName, String attributeValue) {
		when(element.getAttribute(attributeName)).thenReturn(attributeValue);
	}

	protected IConfigurationElement createConfigurationElement(String elementName) {
		IConfigurationElement element = mock(IConfigurationElement.class);
		when(element.getName()).thenReturn(elementName);
		return element;
	}

	public void addDestinationCategory(String categoryId, String categoryName, Class<? extends ISearchDestination> destinationsClass) {
		IConfigurationElement element = createConfigurationElement(DestinationsCategoryExtensionParser.XP_ELEMENT_NAME);
		setAttribute(element, DestinationsCategoryExtensionParser.CATEGORY_ID_ATTRIBUTE, categoryId);
		setAttribute(element, DestinationsCategoryExtensionParser.CATEGORY_DISPLAY_NAME_ATTRIBUTE, categoryName);

		if(destinationsClass!=null) {
			String bundleSymbolicName = FrameworkUtil.getBundle(destinationsClass).getSymbolicName();
			setNamespaceIdentifier(element, bundleSymbolicName);
			setAttribute(element, DestinationsCategoryExtensionParser.DESTINATIONS_CLASS_ATTRIBUTE, destinationsClass.getName());
		}

		destinationCategories.add(element);
	}

	public void addDestinationCategory(String categoryId, String categoryName) {
		addDestinationCategory(categoryId, categoryName, null);
	}

	private void setNamespaceIdentifier(IConfigurationElement element, String bundleSymbolicName) {
		when(element.getNamespaceIdentifier()).thenReturn(bundleSymbolicName);
	}

	public void addMementoLoadProvider(IMementoLoadProvider loadProvider) {
		IConfigurationElement loadProviderElement = createConfigurationElement(MementoLoadProvidersExtensionParser.XP_ELEMENT_NAME);
		setExecutableExtension(loadProviderElement, loadProvider, MementoLoadProvidersExtensionParser.CLASS_ATTR);
		loadProviders.add(loadProviderElement);
	}

	public void addMementoStoreProvider(IMementoStoreProvider storeProvider) {
		IConfigurationElement storeProviderElement = createConfigurationElement(MementoStoreProvidersExtensionParser.XP_ELEMENT_NAME);
		setExecutableExtension(storeProviderElement, storeProvider, MementoStoreProvidersExtensionParser.CLASS_ATTR);
		storeProviders.add(storeProviderElement);		
	}

	public void addSearchProvider(String providerId, String providerFqName, ISearchProvider searchProviderMock, String objectTypeId,
			String providerSupportsTextSearch, String... supportedCategoryIds) {
		IConfigurationElement searchProviderElement = createConfigurationElement(SearchProvidersExtensionParser.XP_ELEMENT_NAME);
		setAttribute(searchProviderElement, SearchProvidersExtensionParser.PROVIDER_ID_ATTR, providerId);
		setAttribute(searchProviderElement, SearchProvidersExtensionParser.PROVIDER_INSTANCE_ATTR, providerFqName);
		setAttribute(searchProviderElement, SearchProvidersExtensionParser.PROVIDER_ID_ATTR, providerId);
		setExecutableExtension(searchProviderElement, searchProviderMock, SearchProvidersExtensionParser.PROVIDER_INSTANCE_ATTR);
		setAttribute(searchProviderElement, SearchProvidersExtensionParser.OBJECT_ID_ATTR, objectTypeId);
		setAttribute(searchProviderElement, SearchProvidersExtensionParser.SUPPORTS_TEXT_SEARCH_ATTR, providerSupportsTextSearch);

		List<IConfigurationElement> categoriesList = new ArrayList<IConfigurationElement>();
		for(String categoryId: supportedCategoryIds) {
			IConfigurationElement categoryElement = mock(IConfigurationElement.class);
			setAttribute(categoryElement, SearchProvidersExtensionParser.CATEGORY_ID_ATTR, categoryId);
			categoriesList.add(categoryElement);
		}
		setChildren(searchProviderElement, categoriesList, SearchProvidersExtensionParser.CATEGORY_ELEMENT_NAME);

		searchProviders.add(searchProviderElement);

	}

	private void setChildren(IConfigurationElement element, List<IConfigurationElement> children, String childrenElementsName) {
		when(element.getChildren(childrenElementsName)).thenReturn(children.toArray(new IConfigurationElement[]{}));
	}

	public void addSearchSubdestination(String id, String displayName, String categoryId, String objectTypeId, String defaultSelected, String... conflicts) {
		IConfigurationElement subdestinationElement = createConfigurationElement(SearchSubdestinationExtensionParser.XP_ELEMENT_NAME);
		setAttribute(subdestinationElement, SearchSubdestinationExtensionParser.ID_ATTR, id);
		setAttribute(subdestinationElement, SearchSubdestinationExtensionParser.DISPLAY_NAME_ATTR, displayName);
		setAttribute(subdestinationElement, SearchSubdestinationExtensionParser.CATEGORY_ID_ATTR, categoryId);
		setAttribute(subdestinationElement, SearchSubdestinationExtensionParser.OBJECT_ATTR, objectTypeId);
		setAttribute(subdestinationElement, SearchSubdestinationExtensionParser.DEFAULT_SELECTED_ATTR, defaultSelected);

		List<IConfigurationElement> conflictsList = new ArrayList<IConfigurationElement>();
		for(String conflictId: conflicts) {
			IConfigurationElement conflictElement = mock(IConfigurationElement.class);
			setAttribute(conflictElement, SearchSubdestinationExtensionParser.CONF_SUBID_ATTR_NAME, conflictId);
			conflictsList.add(conflictElement);
		}
		setChildren(subdestinationElement, conflictsList, SearchSubdestinationExtensionParser.CONFLICT_ELEMENT_NAME);

		searchSubdestinations.add(subdestinationElement);
	}

	public void addAdvancedSearchParamsUiContributor(String id, String searchProviderId, String contributorFQName, IAdvancedSearchParamsUiContributor contributorInstance) {
		IConfigurationElement advancedUiContributorElement = createAdvancedParamsUiElement(id, searchProviderId, contributorFQName);

		setExecutableExtension(advancedUiContributorElement, contributorInstance, AdvancedSearchParamsUiContribXpParser.CONTRIBUTOR_CLASS_NAME_ATTR_NAME);
		advancedSearchUiContributors.add(advancedUiContributorElement);
	}

	private IConfigurationElement createAdvancedParamsUiElement(String id,
			String searchProviderId, String contributorFQName) {
		IConfigurationElement advancedUiContributorElement = createConfigurationElement(AdvancedSearchParamsUiContribXpParser.XP_ELEMENT_NAME);
		setAttribute(advancedUiContributorElement, AdvancedSearchParamsUiContribXpParser.ID_ATTR_NAME, id);
		setAttribute(advancedUiContributorElement, AdvancedSearchParamsUiContribXpParser.SEARCH_PROVIDER_ID_ATTR_NAME, searchProviderId);
		setAttribute(advancedUiContributorElement, AdvancedSearchParamsUiContribXpParser.CONTRIBUTOR_CLASS_NAME_ATTR_NAME, contributorFQName);
		return advancedUiContributorElement;
	}

	public void addExceptionThrowingAdvancedSearchParamsUiContributor(String id, String searchProviderId, String contributorFQName) {
		IConfigurationElement advancedUiContributorElement = createAdvancedParamsUiElement(id, searchProviderId, contributorFQName);
		setupCreateExecutableExtensionToThrowException(advancedUiContributorElement, AdvancedSearchParamsUiContribXpParser.CONTRIBUTOR_CLASS_NAME_ATTR_NAME);
		advancedSearchUiContributors.add(advancedUiContributorElement);
	}

	protected void setupCreateExecutableExtensionToThrowException(IConfigurationElement element, String classAttributeName) {
		setupCreateExecutableExtensionToThrowException(element, classAttributeName, new CoreException(StatusUtils.statusError("TEST")));
	}

	protected void setupCreateExecutableExtensionToThrowException(IConfigurationElement element, String classAttributeName, CoreException toThrow) {
		try {
			when(element.createExecutableExtension(classAttributeName)).thenThrow(toThrow);
		} catch (CoreException e) {
			throw new RuntimeException(e);
		}
	}

	public void addCustomResultUiContributor(String id, String searchProviderId, String contributorFQName, ISearchResultCustomUiCreator cobntributorInstance) {
		IConfigurationElement customResultUiElement = createCustomResultUIElement(id, searchProviderId, contributorFQName);
		setExecutableExtension(customResultUiElement, cobntributorInstance, CustomResultUiXpParser.UI_CREATOR_CLASS_NAME_ATTR_NAME);
		customResultUiContributors.add(customResultUiElement);
	}

	private IConfigurationElement createCustomResultUIElement(String id,
			String searchProviderId, String contributorFQName) {
		IConfigurationElement customResultUiElement = createConfigurationElement(CustomResultUiXpParser.XP_ELEMENT_NAME);
		setAttribute(customResultUiElement, CustomResultUiXpParser.ID_ATTR_NAME, id);
		setAttribute(customResultUiElement, CustomResultUiXpParser.SEARCH_PROVIDER_ID_ATTR_NAME, searchProviderId);
		setAttribute(customResultUiElement, CustomResultUiXpParser.UI_CREATOR_CLASS_NAME_ATTR_NAME, contributorFQName);
		return customResultUiElement;
	}

	public void addExceptionThrowingCustomResultUiContributor(String id, String searchProviderId, String contributorFQName) {
		IConfigurationElement customResultUiElement = createCustomResultUIElement(id, searchProviderId, contributorFQName);
		setupCreateExecutableExtensionToThrowException(customResultUiElement, CustomResultUiXpParser.UI_CREATOR_CLASS_NAME_ATTR_NAME);
		customResultUiContributors.add(customResultUiElement);
	}

	public IExtensionRegistry getRegistry() {
		setupExtensionPointConfigElements();

		clearState();
		return extensionRegistry;
	}

	public void addSearchDestinationsConfigurator(final String id, final String destinationProviderId, final String configuratorFQName, final ISearchDestinationConfigurator<?> configuratorInstance) {
		searchDestinationConfigurators.add(createSearchDestinationsConfiguratorElement(id, destinationProviderId, configuratorFQName, configuratorInstance));
	}

	private IConfigurationElement createSearchDestinationsConfiguratorElement(final String id, final String destinationProviderId, final String configuratorFQName, final ISearchDestinationConfigurator<?> configuratorInstance) {
		try{
			final IConfigurationElement element = createConfigurationElement(SearchDestinationsConfiguratorXPParser.CONFIGURATOR_ELEMENT_NAME);
			setAttribute(element, SearchDestinationsConfiguratorXPParser.CONFIGURATOR_ID_ELEMENT_NAME, id);
			setAttribute(element, SearchDestinationsConfiguratorXPParser.CONFIGURATOR_DEST_PROVIDER_ID_ELEMENT_NAME, destinationProviderId);
			setAttribute(element, SearchDestinationsConfiguratorXPParser.CONFIGURATOR_FQNAME_ELEMENT_NAME, configuratorFQName);
			when(element.createExecutableExtension(eq(SearchDestinationsConfiguratorXPParser.CONFIGURATOR_FQNAME_ELEMENT_NAME))).thenReturn(configuratorInstance);

			return element;
		} catch(CoreException ex) {
			throw new IllegalStateException(ex);
		}

	}

	protected void setupExtensionPointConfigElements() {
		when(objectTypesExtensionPoint.getConfigurationElements()).thenReturn(objectTypes.toArray(new IConfigurationElement[]{}));
		when(destinationProvidersExtensionPoint.getConfigurationElements()).thenReturn(destinationProviders.toArray(new IConfigurationElement[]{}));
		when(destinationCategoriesExtensionPoint.getConfigurationElements()).thenReturn(destinationCategories.toArray(new IConfigurationElement[]{}));
		when(loadProvidersExtensionPoint.getConfigurationElements()).thenReturn(loadProviders.toArray(new IConfigurationElement[]{}));
		when(storeProvidersExtensionPoint.getConfigurationElements()).thenReturn(storeProviders.toArray(new IConfigurationElement[]{}));
		when(searchProvidersExtensionPoint.getConfigurationElements()).thenReturn(searchProviders.toArray(new IConfigurationElement[]{}));
		when(searchSubdestinationsExtensionPoint.getConfigurationElements()).thenReturn(searchSubdestinations.toArray(new IConfigurationElement[]{}));
		when(advancedSearchUiContributorsExtensionPoint.getConfigurationElements()).thenReturn(advancedSearchUiContributors.toArray(new IConfigurationElement[]{}));
		when(customResultUiContributorsExtensionPoint.getConfigurationElements()).thenReturn(customResultUiContributors.toArray(new IConfigurationElement[]{}));
		when(searchDestinationsConfiguratorExtensionPoint.getConfigurationElements()).thenReturn(searchDestinationConfigurators.toArray(new IConfigurationElement[]{}));
	}

	protected void clearState() {
		for(List<?> list: new List<?>[]{objectTypes, destinationProviders, destinationCategories, loadProviders, storeProviders, searchProviders, searchSubdestinations,
				advancedSearchUiContributors, customResultUiContributors, searchDestinationConfigurators})
			list.clear();
	}

}
