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.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);
	}

	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);
	}

	@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(true);
		}
	}

	@Override
	public void addDestination() {
		ContractChecker.nullCheckField(destinationProviderId, "destinationProviderId");
		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);
	}

	@Override
	 public <T extends ISearchDestination> void editDestination() {
		ContractChecker.nullCheckField(destinationProviderId, "destinationProviderId");
		ContractChecker.nullCheckField(destination, "destination");
		
		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");
		ContractChecker.nullCheckField(destination, "destination");
		
		ISearchDestinationConfigurator<T> configurator = getConfigDescription(destinationProviderId).createConfigurator();
		@SuppressWarnings("unchecked") IStatus result = configurator.deleteDestination(view.getShell(), (T)destination);
		updateView(result);		
	}

	@Override
	public void testDestination() {
		throw new RuntimeException("not implemented");
	}

}
