package org.eclipse.team.internal.ccvs.ui.sync;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
 
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.compare.structuremergeviewer.Differencer;
import org.eclipse.compare.structuremergeviewer.ICompareInput;
import org.eclipse.compare.structuremergeviewer.IDiffContainer;
import org.eclipse.compare.structuremergeviewer.IDiffElement;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.sync.ILocalSyncElement;
import org.eclipse.team.core.sync.IRemoteSyncElement;
import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.ICVSFile;
import org.eclipse.team.internal.ccvs.core.ICVSRunnable;
import org.eclipse.team.internal.ccvs.core.client.Session;
import org.eclipse.team.internal.ccvs.core.resources.CVSRemoteSyncElement;
import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
import org.eclipse.team.internal.ccvs.ui.AvoidableMessageDialog;
import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin;
import org.eclipse.team.internal.ccvs.ui.ICVSUIConstants;
import org.eclipse.team.internal.ccvs.ui.Policy;
import org.eclipse.team.internal.ui.sync.CatchupReleaseViewer;
import org.eclipse.team.internal.ui.sync.ChangedTeamContainer;
import org.eclipse.team.internal.ui.sync.ITeamNode;
import org.eclipse.team.internal.ui.sync.SyncCompareInput;
import org.eclipse.team.internal.ui.sync.TeamFile;

public class CVSSyncCompareInput extends SyncCompareInput {
	private IResource[] resources;
	private boolean onlyOutgoing = false;
	
	public CVSSyncCompareInput(IResource[] resources) {
		this(resources, false);
	}
	
	protected CVSSyncCompareInput(IResource[] resources, int granularity) {
		super(granularity);
		this.resources = resources;
	}
	
	public CVSSyncCompareInput(IResource[] resources, boolean onlyOutgoing) {
		super(CVSUIPlugin.getPlugin().getPreferenceStore().getBoolean(ICVSUIConstants.PREF_CONSIDER_CONTENTS) ? ILocalSyncElement.GRANULARITY_CONTENTS : ILocalSyncElement.GRANULARITY_TIMESTAMP);
		this.onlyOutgoing = onlyOutgoing;
		this.resources = resources;		
	}
	
	/**
	 * Overridden to create a custom DiffTreeViewer in the top left pane of the CompareProvider.
	 * 
	 * Subclasses must create and return a new CatchupReleaseViewer, and set the viewer
	 * using setViewer().
	 */
	public Viewer createDiffViewer(Composite parent) {
		CatchupReleaseViewer catchupReleaseViewer = new CVSCatchupReleaseViewer(parent, this);
		setViewer(catchupReleaseViewer);
//		catchupReleaseViewer.getTree().addMouseMoveListener(new MouseMoveListener() {
//			/**
//			 * @see MouseMoveListener#mouseMove(MouseEvent)
//			 */
//			public void mouseMove(MouseEvent e) {
//				final Tree tree = (Tree)e.widget;
//				TreeItem item = tree.getItem(new Point(e.x, e.y));
//				final TeamFile file;
//				if (item != null) {
//					// Hack: this is the only way to get an item from the tree viewer
//					Object o = item.getData();
//					if (o instanceof TeamFile) {
//						file = (TeamFile)o;
//					} else file = null;
//				} else file = null;
//
//				// avoid redundant updates -- identity test is good enough here
// 				if (file == previousTeamFile) return;
//				previousTeamFile = file;
//				getShell().getDisplay().asyncExec(new Runnable() {
//					public void run() {
//						updateToolTip(tree, file);
//					}
//				});
//			}
//		});
		return catchupReleaseViewer;
	}
	
//	protected void updateToolTip(Tree tree, TeamFile file) {
//		String newText = null;
//		if (file != null && file.getChangeDirection() != ITeamNode.OUTGOING) {
//			IRemoteSyncElement element = file.getMergeResource().getSyncElement();
//			final ICVSRemoteFile remoteFile = (ICVSRemoteFile)element.getRemote();
//			final ILogEntry[] logEntry = new ILogEntry[1];
//			if (remoteFile != null) {
//				try {
//					CVSUIPlugin.runWithProgress(getViewer().getTree().getShell(), true /*cancelable*/,
//						new IRunnableWithProgress() {
//						public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
//							try {
//								logEntry[0] = remoteFile.getLogEntry(monitor);
//							} catch (TeamException ex) {
//								throw new InvocationTargetException(ex);
//							}
//						}
//					});
//				} catch (InterruptedException ex) {
//					// ignore cancellation
//				} catch (InvocationTargetException ex) {
//					// ignore the exception
//				}
//			}
//			if (logEntry[0] != null) {
//				newText = logEntry[0].getComment();
//			}
//		}
//		if (tree.isDisposed()) return;
//		String oldText = tree.getToolTipText();
//		if (newText == oldText || newText != null && newText.equals(oldText)) return;
//		tree.setToolTipText(newText);
//	}
	
	protected IRemoteSyncElement[] createSyncElements(IProgressMonitor monitor) throws TeamException {
		if (onlyOutgoing) {
			// Find the outgoing changes in each selected resource
			final List outgoing = new ArrayList();
			try {
				for (int i = 0; i < resources.length; i++) {
					resources[i].accept(new IResourceVisitor() {
						public boolean visit(IResource resource) throws CoreException {
							// if resource is a file and is dirty, add it to the list
							if (resource.getType() == IResource.FILE) {
								if (isDirty((IFile)resource)) {
									outgoing.add(resource);
								}
							}
							return true;
						}
					});
				}
			} catch (CoreException e) {
				ErrorDialog.openError(getShell(), Policy.bind("simpleInternal"), Policy.bind("internal"), e.getStatus()); //$NON-NLS-1$ //$NON-NLS-2$
				CVSUIPlugin.log(e.getStatus());
				return new IRemoteSyncElement[0];
			}
			final TeamException[] exception = new TeamException[1];
			final IFile[] files = (IFile[])outgoing.toArray(new IFile[outgoing.size()]);
			final IRemoteSyncElement[] trees = new IRemoteSyncElement[files.length];
			Session.run(null, null, true, new ICVSRunnable() {
				public void run(IProgressMonitor monitor) throws CVSException {
					int work = 1000 * resources.length;
					monitor.beginTask(null, work);
					try {
						for (int i = 0; i < trees.length; i++) {
							trees[i] = CVSWorkspaceRoot.getRemoteSyncTree(files[i], null, Policy.subMonitorFor(monitor, 1000));
						}
					} catch (TeamException e) {
						exception[0] = e;
					} finally {
						monitor.done();
					}
				}
			}, monitor);
			if (exception[0] != null) throw exception[0];
			return trees;
		} else {
			IRemoteSyncElement[] trees = new IRemoteSyncElement[resources.length];
			int work = 1000 * resources.length;
			monitor.beginTask(null, work);
			try {
				for (int i = 0; i < trees.length; i++) {
					trees[i] = CVSWorkspaceRoot.getRemoteSyncTree(resources[i], null, Policy.subMonitorFor(monitor, 1000));
				}
			} finally {
				monitor.done();
			}
			return trees;
		}
	}

	protected void updateView() {
		// Update the view
		if (getDiffRoot().hasChildren()) {
			getViewer().refresh();
		} else {
			getViewer().setInput(null);
		}
		
		// Update the status line
		updateStatusLine();
	}
	
	/**
	 * Overridden to mark the source as merged.
	 */
	protected void compareInputChanged(ICompareInput source) {
		super.compareInputChanged(source);
		updateView();
		
		// prompt user with warning
		Shell shell = getShell();
		if(shell != null) {
			// prompt
			if(source instanceof TeamFile) {
				TeamFile file = (TeamFile)source;						
				int direction = file.getChangeDirection();
				int type = file.getChangeType();
				if(direction == IRemoteSyncElement.INCOMING ||
				   direction == IRemoteSyncElement.CONFLICTING) {
					promptForConfirmMerge(getShell());
			    }
			}
		}
	}
	
	/*
	 * Helper method to get cvs elements from the selection in the sync editor input
	 */
	public static CVSRemoteSyncElement getSyncElementFrom(Object node) {
		CVSRemoteSyncElement element = null;
		if (node instanceof TeamFile) {
			element = (CVSRemoteSyncElement)((TeamFile)node).getMergeResource().getSyncElement();
		} else if (node instanceof ChangedTeamContainer) {
			element = (CVSRemoteSyncElement)((ChangedTeamContainer)node).getMergeResource().getSyncElement();
		}
		return element;
	}
	
	/*
	 * Returns the resources in this input.
	 */
	public IResource[] getResources() {
		return resources;
	}
	
	/*
	 * Inform user that when changes are merged in the sync view that confirm
	 * merge should be called to finish the merge.
	 */
	private void promptForConfirmMerge(final Shell shell) {
		final IPreferenceStore store = CVSUIPlugin.getPlugin().getPreferenceStore();
		if(!store.getBoolean(ICVSUIConstants.PREF_PROMPT_ON_SAVING_IN_SYNC)) {
			return;
		};
		shell.getDisplay().syncExec(new Runnable() {
			public void run() {							
				AvoidableMessageDialog dialog = new AvoidableMessageDialog(
						shell,
						Policy.bind("CVSSyncCompareInput.confirmMergeMessageTitle"),  //$NON-NLS-1$
						null,	// accept the default window icon
						Policy.bind("CVSSyncCompareInput.confirmMergeMessage"),  //$NON-NLS-1$
						MessageDialog.INFORMATION, 
						new String[] {IDialogConstants.OK_LABEL}, 
						0);
				dialog.open();		
				if(dialog.isDontShowAgain()) {
					store.setValue(ICVSUIConstants.PREF_PROMPT_ON_SAVING_IN_SYNC, false);
				}																				
			}
		});
	}
	
	/**
	 * Wrap the input preparation in a CVS session run so open sessions will be reused and
	 * file contents under the same remote root folder will be fetched using the same connection.
	 * 
	 * Also run with refresh prompting if one of the resources is out of sync with the local
	 * file system.
	 */
	public Object prepareInput(IProgressMonitor pm) throws InterruptedException, InvocationTargetException {
		final Object[] result = new Object[] { null };
		final Exception[] exception = new Exception[] {null};
		try {
			Session.run(null, null, false, new ICVSRunnable() {
				public void run(IProgressMonitor monitor) throws CVSException {
					try {
						CVSUIPlugin.runWithRefresh(getShell(), resources, new IRunnableWithProgress() {
							public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
								result[0] = CVSSyncCompareInput.super.prepareInput(monitor);
							}
						}, monitor);
					} catch (InterruptedException e) {
						exception[0] = e;
					} catch (InvocationTargetException e) {
						exception[0] = e;
					}
				}
			}, pm);
		} catch (CVSException e) {
			throw new InvocationTargetException(e);
		}
		
		if (exception[0] != null) {
			if (exception[0] instanceof InvocationTargetException) {
				throw (InvocationTargetException)exception[0];
			} else {
				throw (InterruptedException)exception[0];
			}
		}
			
		return result[0];
	}
	
	/**
	 * Adjust the sync info (to conflicting change) for locally deleted 
	 * folders (i.e. outgoing folder deletions)
	 * that have incoming or conflicting changes in one or more children.
	 * 
	 * @see MergeAction#removeNodes(ITeamNode[])
	 */
	protected IDiffElement collectResourceChanges(IDiffContainer parent, IRemoteSyncElement tree, IProgressMonitor pm) {
		IDiffElement element = super.collectResourceChanges(parent, tree, pm);
		int kind = element.getKind();
		if ((element instanceof ChangedTeamContainer) 
				&& ((kind & Differencer.CHANGE_TYPE_MASK) == Differencer.DELETION) 
				&& ((kind & Differencer.DIRECTION_MASK) == ITeamNode.OUTGOING)) {
			// Check the children to see if there are any incomming changes
			if (hasIncomingChanges((ChangedTeamContainer)element)) {
				((ChangedTeamContainer)element).setKind(ITeamNode.CONFLICTING | Differencer.CHANGE);
			}
		}
		return element;
	}
	
	private boolean hasIncomingChanges(ChangedTeamContainer container) {
		IDiffElement[] children = container.getChildren();
		for (int i = 0; i < children.length; i++) {
			IDiffElement element = children[i];
			int direction = element.getKind() & Differencer.DIRECTION_MASK;
			if (direction == ITeamNode.CONFLICTING || direction == ITeamNode.INCOMING) {
				return true;
			}
			if (element instanceof ChangedTeamContainer)  {
				boolean hasIncomingChanges = hasIncomingChanges((ChangedTeamContainer)element);
				if (hasIncomingChanges) return true;
			}
		}
		return false;
	}
	
	/*
	 * Copied from CVSDecorator
	 */
	private static boolean isDirty(ICVSFile cvsFile) {
		try {
			// file is dirty or file has been merged by an update
			if(!cvsFile.isIgnored()) {
				return cvsFile.isModified();
			} else {
				return false;
			} 
		} catch (CVSException e) {
			//if we get an error report it to the log but assume dirty
			CVSUIPlugin.log(e.getStatus());
			return true;
		}
	}

	/*
	 * Copied from CVSDecorator
	 */
	private static boolean isDirty(IFile file) {
		return isDirty(CVSWorkspaceRoot.getCVSFileFor(file));
	}
}
