package org.eclipse.platform.discovery.destprefs.internal.prefpage.ui;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.platform.discovery.destprefs.api.ISearchDestinationConfigurator;
import org.eclipse.platform.discovery.destprefs.api.ISearchDestinationTester;
import org.eclipse.platform.discovery.destprefs.internal.xpparser.ISearchDestinationsConfiguratorDescription;
import org.eclipse.platform.discovery.destprefs.internal.xpparser.SearchDestinationsConfiguratorXPParser;
import org.eclipse.platform.discovery.runtime.api.ISearchDestination;
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.util.internal.ContractChecker;

public class DestinationConfiguratorsPresenter implements IDestinationConfiguratorsPresenter {

	private final SearchDestinationsConfiguratorXPParser configuratorParser;
	private IDestinationConfiguratorsView view;
	private final ISearchProviderConfiguration searchConfig;

	
	private ISearchDestination destination;
	private String destinationProviderId;
	
	public DestinationConfiguratorsPresenter(final SearchDestinationsConfiguratorXPParser configuratorParser, final ISearchProviderConfiguration searchConfig) {
		this.configuratorParser = configuratorParser;
		this.searchConfig = searchConfig;
	}
	
	@Override
	public void setView(IDestinationConfiguratorsView view) {
		ContractChecker.nullCheckParam(view);
		this.view = view;
		view.setInput(buildInput());
	}
	

	private Collection<CategoryDestinationProviderPair> buildInput() {
		List<CategoryDestinationProviderPair> result = new ArrayList<CategoryDestinationProviderPair>();
		for(ISearchDestinationsConfiguratorDescription desc: configuratorParser.readContributions()) {
			IDestinationCategoryDescription category = findCategory(desc.destinationCategoryId());
			IDestinationsProviderDescription destinationProvider = findProvider(desc.destinationProviderId(), category);
			result.add(new CategoryDestinationProviderPair(category, destinationProvider));
		}
		return result;
	}

	private IDestinationsProviderDescription findProvider(String destinationProviderId, IDestinationCategoryDescription category) {
		for(IDestinationsProviderDescription provider: searchConfig.getDestinationProvidersForCategory(category)) {
			if(provider.getId().equals(destinationProviderId)) {
				return provider;
			}
		}
		throw new RuntimeException("cannot find dest provider:"+destinationProviderId); //$NON-NLS-1$
	}

	private IDestinationCategoryDescription findCategory(String destinationCategoryId) {
		for(IDestinationCategoryDescription category: searchConfig.getDestinationCategories()) {
			if(category.getId().equals(destinationCategoryId)) {
				return category;
			}
		}
		throw new RuntimeException("cannot find dest category:"+destinationCategoryId); //$NON-NLS-1$
	}

	@Override
	public void selectionChanged(DestinationConfiguratorSelection selection) {
		ContractChecker.nullCheckParam(selection.destProviderId);

		destinationProviderId = selection.destProviderId;
		destination = selection.destination;
		
		if(destination==null) {
			view.setAddEnabled(true);
			view.setEditEnabled(false);
			view.setRemoveEnabled(false);
			view.setTestEnabled(false);
		} else{
			view.setAddEnabled(true);
			view.setEditEnabled(true);
			view.setRemoveEnabled(true);
			view.setTestEnabled(getConfigDescription(destinationProviderId).createConfigurator().getSearchDestinationTester()!=null);
		}
	}

	@Override
	public void addDestination() {
		ContractChecker.nullCheckField(destinationProviderId, "destinationProviderId"); //$NON-NLS-1$
		ISearchDestinationConfigurator<?> configurator = getConfigDescription(destinationProviderId).createConfigurator();
		IStatus result = configurator.createDestination(view.getShell());
		updateView(result);
	}

	private void updateView(IStatus result) {
		view.setStatus(result);
		if(result.isOK()) {
			view.setInput(buildInput());
		}
	}

	private ISearchDestinationsConfiguratorDescription getConfigDescription(String destinationProviderId) {
		for(ISearchDestinationsConfiguratorDescription desc: configuratorParser.readContributions()) {
			if(desc.destinationProviderId().equals(destinationProviderId)) {
				return desc;
			}
		}
		throw new RuntimeException("cannot find destination configurator for dest provider id:"+destinationProviderId); //$NON-NLS-1$
	}

	@Override
	 public <T extends ISearchDestination> void editDestination() {
		ContractChecker.nullCheckField(destinationProviderId, "destinationProviderId"); //$NON-NLS-1$
		ContractChecker.nullCheckField(destination, "destination"); //$NON-NLS-1$
		
		ISearchDestinationConfigurator<T> configurator = getConfigDescription(destinationProviderId).createConfigurator();
		@SuppressWarnings("unchecked") IStatus result = configurator.editDestination(view.getShell(), (T)destination);
		updateView(result);
		
	}

	@Override
	public <T extends ISearchDestination> void removeDestination() {
		ContractChecker.nullCheckField(destinationProviderId, "destinationProviderId"); //$NON-NLS-1$
		ContractChecker.nullCheckField(destination, "destination"); //$NON-NLS-1$
		
		ISearchDestinationConfigurator<T> configurator = getConfigDescription(destinationProviderId).createConfigurator();
		@SuppressWarnings("unchecked") IStatus result = configurator.deleteDestination(view.getShell(), (T)destination);
		updateView(result);		
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T extends ISearchDestination> void testDestination() {
		ContractChecker.nullCheckField(destinationProviderId, "destinationProviderId"); //$NON-NLS-1$
		ContractChecker.nullCheckField(destination, "destination"); //$NON-NLS-1$
		ISearchDestinationTester<T> tester = (ISearchDestinationTester<T>) getConfigDescription(destinationProviderId).createConfigurator().getSearchDestinationTester();
		IStatus result = tester.test(view.getShell(), (T)destination);
		view.setStatus(result);
	}

}
