/*******************************************************************************
 * Copyright (c) 2006 IBM Corporation and others.
 * 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:
 * IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.team.examples.model.ui.mapping;

import java.util.*;

import org.eclipse.core.resources.*;
import org.eclipse.core.resources.mapping.*;
import org.eclipse.core.runtime.*;
import org.eclipse.jface.viewers.*;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.team.core.diff.*;
import org.eclipse.team.core.mapping.ISynchronizationContext;
import org.eclipse.team.core.mapping.ISynchronizationScope;
import org.eclipse.team.core.mapping.provider.ResourceDiffTree;
import org.eclipse.team.examples.filesystem.FileSystemPlugin;
import org.eclipse.team.examples.model.*;
import org.eclipse.team.examples.model.mapping.ExampleModelProvider;
import org.eclipse.team.examples.model.ui.ModelNavigatorContentProvider;
import org.eclipse.team.internal.ui.Utils;
import org.eclipse.team.internal.ui.mapping.SynchronizationResourceMappingContext;
import org.eclipse.team.ui.mapping.SynchronizationContentProvider;
import org.eclipse.ui.navigator.*;

/**
 * The content provider that is used for synchronizations.
 * It also makes use of the Common Navigator pipeline 
 * to override the resource content extension so that model projects will
 * replace the corresponding resource project in the Synchronize view.
 */
public class ModelSyncContentProvider extends SynchronizationContentProvider implements IPipelinedTreeContentProvider {

	private ModelNavigatorContentProvider delegate;
	
	public ModelSyncContentProvider() {
		super();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.team.ui.mapping.SynchronizationContentProvider#init(org.eclipse.ui.navigator.ICommonContentExtensionSite)
	 */
	public void init(ICommonContentExtensionSite site) {
		super.init(site);
		delegate = new ModelNavigatorContentProvider(getContext() != null);
		delegate.init(site);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.team.ui.mapping.SynchronizationContentProvider#dispose()
	 */
	public void dispose() {
		super.dispose();
		if (delegate != null)
			delegate.dispose();
	}
	
	protected ITreeContentProvider getDelegateContentProvider() {
		return delegate;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.team.ui.mapping.SynchronizationContentProvider#getModelProviderId()
	 */
	protected String getModelProviderId() {
		return ExampleModelProvider.ID;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.team.ui.mapping.SynchronizationContentProvider#getModelRoot()
	 */
	protected Object getModelRoot() {
		return ModelWorkspace.getRoot();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.team.ui.mapping.SynchronizationContentProvider#getTraversals(org.eclipse.team.core.mapping.ISynchronizationContext, java.lang.Object)
	 */
	protected ResourceTraversal[] getTraversals(
			ISynchronizationContext context, Object object) {
		if (object instanceof ModelObject) {
			ModelObject mo = (ModelObject) object;
			ResourceMapping mapping = (ResourceMapping)mo.getAdapter(ResourceMapping.class);
			ResourceMappingContext rmc = new SynchronizationResourceMappingContext(context);
			try {
				// Technically speaking, this may end up being too long running for this
				// (i.e. we may end up hitting the server) but it will do for illustration purposes
				return mapping.getTraversals(rmc, new NullProgressMonitor());
			} catch (CoreException e) {
				FileSystemPlugin.log(e.getStatus());
			}
		}
		return new ResourceTraversal[0];
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.team.ui.mapping.SynchronizationContentProvider#getChildrenInContext(org.eclipse.team.core.mapping.ISynchronizationContext, java.lang.Object, java.lang.Object[])
	 */
	protected Object[] getChildrenInContext(ISynchronizationContext context, Object parent, Object[] children) {
		Set allChildren = new HashSet();
		allChildren.addAll(Arrays.asList(super.getChildrenInContext(context, parent, children)));
		// We need to override this method in order to ensure that any elements
		// that exist in the context but do not exist locally are included
		if (parent instanceof ModelContainer) {
			ModelContainer mc = (ModelContainer) parent;
			IDiff[] diffs = context.getDiffTree().getDiffs(mc.getResource(), IResource.DEPTH_ONE);
			for (int i = 0; i < diffs.length; i++) {
				IDiff diff = diffs[i];
				IResource resource = ResourceDiffTree.getResourceFor(diff);
				if (!resource.exists() && ModelObjectDefinitionFile.isModFile(resource)) {
					ModelObject o = ModelObject.create(resource);
					if (o != null)
						allChildren.add(o);
				}
			}
		}
		if (parent instanceof ModelObjectDefinitionFile) {
			ResourceTraversal[] traversals = getTraversals(context, parent);
			IDiff[] diffs = context.getDiffTree().getDiffs(traversals);
			for (int i = 0; i < diffs.length; i++) {
				IDiff diff = diffs[i];
				IResource resource = ResourceDiffTree.getResourceFor(diff);
				if (!resource.exists() && ModelObjectElementFile.isMoeFile(resource)) {
					ModelObject o = new ModelObjectElementFile((ModelObjectDefinitionFile)parent, (IFile)resource);
					if (o != null)
						allChildren.add(o);
				}
			}
		}
		return allChildren.toArray(new Object[allChildren.size()]);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.navigator.IPipelinedTreeContentProvider#getPipelinedChildren(java.lang.Object, java.util.Set)
	 */
	public void getPipelinedChildren(Object aParent, Set theCurrentChildren) {
		// Nothing to do
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.navigator.IPipelinedTreeContentProvider#getPipelinedElements(java.lang.Object, java.util.Set)
	 */
	public void getPipelinedElements(Object anInput, Set theCurrentElements) {
		// Replace any model projects with a ModelProject if the input
		// is a synchronization context
		if (anInput instanceof ISynchronizationContext) {
			List newProjects = new ArrayList();
			for (Iterator iter = theCurrentElements.iterator(); iter.hasNext();) {
				Object element = iter.next();
				if (element instanceof IProject) {
					IProject project = (IProject) element;
					try {
						if (ModelProject.isModProject(project)) {
							iter.remove();
							newProjects.add(ModelObject.create(project));
						}
					} catch (CoreException e) {
						FileSystemPlugin.log(e.getStatus());
					}
				}
			}
			theCurrentElements.addAll(newProjects);
		} else if (anInput instanceof ISynchronizationScope) {
			// When the root is a scope, we should return
			// our model provider so all model providers appear
			// at the root of the viewer.
			theCurrentElements.add(getModelProvider());
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.navigator.IPipelinedTreeContentProvider#getPipelinedParent(java.lang.Object, java.lang.Object)
	 */
	public Object getPipelinedParent(Object anObject, Object aSuggestedParent) {
		// We're not changing the parenting of any resources
		return aSuggestedParent;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.navigator.IPipelinedTreeContentProvider#interceptAdd(org.eclipse.ui.navigator.PipelinedShapeModification)
	 */
	public PipelinedShapeModification interceptAdd(PipelinedShapeModification anAddModification) {
		if (anAddModification.getParent() instanceof ISynchronizationContext) {
			for (Iterator iter = anAddModification.getChildren().iterator(); iter.hasNext();) {
				Object element = iter.next();
				if (element instanceof IProject) {
					IProject project = (IProject) element;
					try {
						if (ModelProject.isModProject(project)) {
							iter.remove();
						}
					} catch (CoreException e) {
						FileSystemPlugin.log(e.getStatus());
					}
				}
			}
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.navigator.IPipelinedTreeContentProvider#interceptRefresh(org.eclipse.ui.navigator.PipelinedViewerUpdate)
	 */
	public boolean interceptRefresh(PipelinedViewerUpdate aRefreshSynchronization) {
		// No need to intercept the refresh
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.navigator.IPipelinedTreeContentProvider#interceptRemove(org.eclipse.ui.navigator.PipelinedShapeModification)
	 */
	public PipelinedShapeModification interceptRemove(PipelinedShapeModification aRemoveModification) {
		// No need to intercept the remove
		return aRemoveModification;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.navigator.IPipelinedTreeContentProvider#interceptUpdate(org.eclipse.ui.navigator.PipelinedViewerUpdate)
	 */
	public boolean interceptUpdate(PipelinedViewerUpdate anUpdateSynchronization) {
		// No need to intercept the update
		return false;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.team.ui.mapping.SynchronizationContentProvider#diffsChanged(org.eclipse.team.core.diff.IDiffChangeEvent, org.eclipse.core.runtime.IProgressMonitor)
	 */
	public void diffsChanged(final IDiffChangeEvent event, IProgressMonitor monitor) {
		// Override in order to perform custom viewer updates when the diff tree changes
		Utils.syncExec(new Runnable() {
			public void run() {
				handleChange(event);
			}
		}, (StructuredViewer)getViewer());
	}

	void handleChange(IDiffChangeEvent event) {
		Set existingProjects = getVisibleModelProjects();
		IProject[] changedProjects = getChangedModelProjects(event);
		List refreshes = new ArrayList(changedProjects.length);
		List additions = new ArrayList(changedProjects.length);
		List removals = new ArrayList(changedProjects.length);
		for (int i = 0; i < changedProjects.length; i++) {
			IProject project = changedProjects[i];
			if (hasVisibleChanges(event.getTree(), project)) {
				if (existingProjects.contains(project)) {
					refreshes.add(ModelObject.create(project));
				} else {
					additions.add(ModelObject.create(project));
				}
			} else if (existingProjects.contains(project)) {
				removals.add(ModelObject.create(project));
				
			}
		}
		if (!removals.isEmpty() || !additions.isEmpty() || !refreshes.isEmpty()) {
			TreeViewer viewer = (TreeViewer)getViewer();
			Tree tree = viewer.getTree();
			try {
				tree.setRedraw(false);
				if (!additions.isEmpty())
					viewer.add(viewer.getInput(), additions.toArray());
				if (!removals.isEmpty())
					viewer.remove(viewer.getInput(), removals.toArray());
				if (!refreshes.isEmpty()) {
					for (Iterator iter = refreshes.iterator(); iter.hasNext();) {
						Object element = iter.next();
						viewer.refresh(element);
					}
				}
			} finally {
				tree.setRedraw(true);
			}
		}
	}

	private boolean hasVisibleChanges(IDiffTree tree, IProject project) {
		return tree.hasMatchingDiffs(project.getFullPath(), new FastDiffFilter() {
			public boolean select(IDiff diff) {
				return isVisible(diff);
			}
		});
	}

	/*
	 * Return the list of all projects that are model projects
	 */
	private IProject[] getChangedModelProjects(IDiffChangeEvent event) {
		Set result = new HashSet();
		IDiff[] changes = event.getChanges();
		for (int i = 0; i < changes.length; i++) {
			IDiff diff = changes[i];
			IResource resource = ResourceDiffTree.getResourceFor(diff);
			if (resource != null && isModProject(resource.getProject())) {
				result.add(resource.getProject());
			}
		}
		IDiff[] additions = event.getAdditions();
		for (int i = 0; i < additions.length; i++) {
			IDiff diff = additions[i];
			IResource resource = ResourceDiffTree.getResourceFor(diff);
			if (resource != null && isModProject(resource.getProject())) {
				result.add(resource.getProject());
			}
		}
		IPath[] removals = event.getRemovals();
		for (int i = 0; i < removals.length; i++) {
			IPath path = removals[i];
			if (path.segmentCount() > 0) {
				IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(path.segment(0));
				if (isModProject(project))
					result.add(project);
			}
		}
		return (IProject[]) result.toArray(new IProject[result.size()]);
	}

	private boolean isModProject(IProject project) {
		try {
			return ModelProject.isModProject(project);
		} catch (CoreException e) {
			FileSystemPlugin.log(e.getStatus());
		}
		return false;
	}

	/*
	 * Return the set of visible model projects
	 */
	private Set getVisibleModelProjects() {
		TreeViewer viewer = (TreeViewer)getViewer();
		Tree tree = viewer.getTree();
		TreeItem[] children = tree.getItems();
		Set result = new HashSet();
		for (int i = 0; i < children.length; i++) {
			TreeItem control = children[i];
			Object data = control.getData();
			if (data instanceof ModelProject) {
				result.add(((ModelProject) data).getProject());
			}
		}
		return result;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.team.ui.mapping.SynchronizationContentProvider#propertyChanged(org.eclipse.team.core.diff.IDiffTree, int, org.eclipse.core.runtime.IPath[])
	 */
	public void propertyChanged(IDiffTree tree, int property, IPath[] paths) {
		// We're overriding this message so that label updates occur for any elements
		// whose labels may have changed
		if (getContext() == null)
			return;
		final Set updates = new HashSet();
		boolean refresh = false;
		for (int i = 0; i < paths.length; i++) {
			IPath path = paths[i];
			IDiff diff = tree.getDiff(path);
			if (diff != null) {
				IResource resource = ResourceDiffTree.getResourceFor(diff);
				ModelObject object = ModelObject.create(resource);
				if (object != null) {
					updates.add(object);
				} else {
					// If the resource is a MOE file, we need to update both the MOE and the MOD file
					// Unfortunately, there's no good way to find the parent file so we'll just refresh everything
					refresh = true;
				}
			}
		}
		if (!updates.isEmpty() || refresh) {
			final boolean refreshAll = refresh;
			final StructuredViewer viewer = (StructuredViewer)getViewer();
			Utils.syncExec(new Runnable() {
				public void run() {
					if (refreshAll)
						viewer.refresh(true);
					else
						viewer.update(updates.toArray(new Object[updates.size()]), null);
				}
			}, viewer);
		}
	}

}
