package org.eclipse.platform.discovery.destprefs.internal;

import java.util.LinkedList;
import java.util.List;

import org.eclipse.platform.discovery.core.internal.IDestinationsManager;
import org.eclipse.platform.discovery.destprefs.internal.xpparser.ISearchDestinationsConfiguratorDescription;
import org.eclipse.platform.discovery.runtime.internal.ISearchProviderConfiguration;
import org.eclipse.platform.discovery.runtime.internal.model.descriptions.IDestinationCategoryDescription;
import org.eclipse.platform.discovery.runtime.internal.model.descriptions.IDestinationsProviderDescription;
import org.eclipse.platform.discovery.runtime.internal.xp.impl.AbstractExtensionPointParser;
import org.eclipse.swt.widgets.Shell;

public class DestinationsManager implements IDestinationsManager {

	public static final String GENERIC_PREFPAGE_ID = "org.eclipse.platform.discovery.destprefs.preferencepage"; //$NON-NLS-1$

	private final AbstractExtensionPointParser<ISearchDestinationsConfiguratorDescription> destConfigurator;
	private final ISearchProviderConfiguration searchConfig;
	private final IPreferenceDialogCreator dialogCreator;

	public DestinationsManager(AbstractExtensionPointParser<ISearchDestinationsConfiguratorDescription> destConfigurator, IPreferenceDialogCreator dialogCreator,
			ISearchProviderConfiguration searchConfig) {
		this.destConfigurator = destConfigurator;
		this.dialogCreator = dialogCreator;
		this.searchConfig = searchConfig;
	}

	@Override
	public void manageDestinations(Shell parentShell, IDestinationCategoryDescription selectedDestCategory) {

		final List<String> prefPageIDs = allPreferencePages();
		dialogCreator.openPreferenceDialog(parentShell, getPrefPageIdToPreselect(selectedDestCategory), prefPageIDs.toArray(new String[prefPageIDs.size()]));

	}

	private List<String> allPreferencePages() {
		final List<String> prefPageIDs = new LinkedList<String>(); 
		prefPageIDs.add(GENERIC_PREFPAGE_ID);
		for (IDestinationsProviderDescription provider: searchConfig.getAvailableDestinationProviders()) {
			if (provider.getPreferencePageId()!=null) {
				prefPageIDs.add(provider.getPreferencePageId());
			}
		}
		return prefPageIDs;
	}

	private String getPrefPageIdToPreselect(IDestinationCategoryDescription selectedDestCategory) {
		if(selectedDestCategory!=null && !hasDestinationsConfigurator(selectedDestCategory)) {
			String prefPageId = getPrefPageIdFor(selectedDestCategory);
			if(prefPageId!=null) {
				return prefPageId;
			}
		}

		return GENERIC_PREFPAGE_ID;
	}

	private String getPrefPageIdFor(IDestinationCategoryDescription selectedDestCategory) {
		for(IDestinationsProviderDescription destProvider: searchConfig.getDestinationProvidersForCategory(selectedDestCategory)) {
			if(destProvider.getPreferencePageId()!=null) {
				return destProvider.getPreferencePageId();
			}
		}
		return null;
	}

	private boolean hasDestinationsConfigurator(IDestinationCategoryDescription selectedDestCategory) {
		for(IDestinationsProviderDescription destProvider: searchConfig.getDestinationProvidersForCategory(selectedDestCategory)) {
			for(ISearchDestinationsConfiguratorDescription desc: destConfigurator.readContributions()) {
				if(desc.destinationProviderId().equals(destProvider.getId()) && desc.destinationCategoryId().equals(selectedDestCategory.getId())) {
					return true;
				}
			}
		}
		return false;
	}

}
