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) {
	    destination = selection.destination;
	    destinationProviderId = selection.destProviderId;
	    if(destination != null) {
	        ContractChecker.nullCheckField(destinationProviderId, "destinationProviderId");
	    }
	    
		view.setAddEnabled(destinationProviderId != null);
		if(destination==null) {
			view.setEditEnabled(false);
			view.setRemoveEnabled(false);
			view.setTestEnabled(false);
		} else{
			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);
	}
}
