//------------------------------------------------------------------------------
// Copyright (c) 2005, 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.library.edit.process.command;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;

import org.eclipse.emf.common.CommonPlugin;
import org.eclipse.emf.common.command.BasicCommandStack;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.util.AbstractTreeIterator;
import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.emf.edit.command.RemoveCommand;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.epf.library.edit.IConfigurator;
import org.eclipse.epf.library.edit.LibraryEditPlugin;
import org.eclipse.epf.library.edit.LibraryEditResources;
import org.eclipse.epf.library.edit.Providers;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.command.IResourceAwareCommand;
import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
import org.eclipse.epf.library.edit.util.Messenger;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.Deliverable;
import org.eclipse.epf.uma.Descriptor;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.Role;
import org.eclipse.epf.uma.RoleDescriptor;
import org.eclipse.epf.uma.Task;
import org.eclipse.epf.uma.TaskDescriptor;
import org.eclipse.epf.uma.TeamProfile;
import org.eclipse.epf.uma.WorkProduct;
import org.eclipse.epf.uma.WorkProductDescriptor;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.Display;


/**
 * Command for one-way synchronization from method to process.
 * 
 * @author Phong Nguyen Le - Nov 22, 2005
 * @since 1.0
 */
public class SynchronizeCommand extends CompoundCommand implements
		IResourceAwareCommand {

	private Collection elements;

	private IConfigurator configurator;

	protected boolean aborted;

	private ArrayList deleteList;

	protected boolean preExecSuccessful;

	protected List deleteCommandList;

	protected boolean successful;

	private MethodConfiguration config;

	private Set synchFeatures;

	private DeleteUnusedDescriptorsCommand deleteUnusedDescriptorsCommand;
	
	private Collection activities;

	private boolean showSuccessfulMsg = true;

	private boolean intialized;

//	private Object UIContext;

	/**
	 * Constructs a SynchronizeCommand that use the process default
	 * configuration to synchronize all the synchronizable features
	 * 
	 * @param elements
	 *            a list of BreakdownElement objects
	 */
	public SynchronizeCommand(String label, Collection elements) {
		super(label);
		this.elements = elements;
	}
	
	/**
	 * Constructs a SynchronizeCommand that use the given configuration 
	 * and list of synchronizable features to synchronize
	 * 
	 * @param elements
	 * @param config the configuration
	 * @param synchFeatures the synchronizable features
	 */
	public SynchronizeCommand(Collection elements, MethodConfiguration config, Set synchFeatures, boolean showSuccessfulMsg) {
		super(LibraryEditResources.AutoSynchronizeCommand_label); 
		this.elements = elements;
		this.config = config;
		this.synchFeatures = synchFeatures;
		this.showSuccessfulMsg = showSuccessfulMsg; 
	}
	
	public void setMethodConfiguration(MethodConfiguration config) {
		this.config = config;
		if(configurator != null) {
			configurator.setMethodConfiguration(config);
		}
	}
	
	public void setSynchronizationFeatures(Set synchFeatures) {
		this.synchFeatures = synchFeatures;
	}
	
	private boolean doInitialize() {
		if (elements == null || elements.isEmpty()) {
			return false;
		}

		deleteCommandList = new ArrayList();
		deleteList = new ArrayList();
		activities = new ArrayList();
		for (Iterator iter = elements.iterator(); iter.hasNext();) {
			Object element = (Object) iter.next();
			addToDeleteList(element, deleteList);
			if(element instanceof Activity) {
				activities.add(element);
			}
		}
		elements.removeAll(deleteList);

		for (Iterator iter = elements.iterator(); iter.hasNext();) {
			Object object = iter.next();
			if (object instanceof Descriptor) {
				Descriptor descriptor = (Descriptor) object;
				if (descriptor.getIsSynchronizedWithSource().booleanValue()
						&& !deleteList.contains(descriptor)) {
					if(descriptor.getSuperActivities() == null) {						
						// descriptor is used by TeamProfile to represent a role or used by a deliverable descriptor to
						// represent a deliverable part
						//
						if(descriptor instanceof WorkProductDescriptor && ((WorkProductDescriptor)descriptor).getWorkProduct() instanceof Deliverable) {
							append(new SynchronizeDeliverableDescriptorCommand((WorkProductDescriptor) descriptor, synchFeatures, config));
						}
						else {
							append(new BasicSynchronizeDescriptorCommand(descriptor, synchFeatures, config));
						}
					}
					else {
						Activity act = descriptor.getSuperActivities();
						if (object instanceof TaskDescriptor) {
							Task task = ((TaskDescriptor) object).getTask();
							if (task != null) {
								append(new WBSDropCommand(act, Collections
										.singletonList(task), config, synchFeatures));
							}
						} else if (object instanceof RoleDescriptor) {
							Role role = ((RoleDescriptor) object).getRole();
							if (role != null) {
								append(new OBSDropCommand(act, Collections
										.singletonList(role), config, synchFeatures, configurator));
							}
						} else if (object instanceof WorkProductDescriptor) {
							WorkProduct wp = ((WorkProductDescriptor) object)
							.getWorkProduct();
							if (wp != null) {
								append(new PBSDropCommand(act, Collections
										.singletonList(wp), config, synchFeatures, configurator));
							}
						}
					}
				}
			} else if (object instanceof Activity) {
				appendCommands((Activity) object);
			} else if (object instanceof TeamProfile) {
				appendCommands((TeamProfile)object);
			}
		}
		return !deleteList.isEmpty() || !commandList.isEmpty() || !activities.isEmpty();
	}

	public boolean initilize() {
		return intialized = doInitialize();		
	}
	
	/**
	 * @return the intialized
	 */
	public boolean isIntialized() {
		return intialized;
	}

	/**
	 * @param activity
	 */
	private void appendCommands(Activity activity) {
		List tasks = new ArrayList();
		List roles = new ArrayList();
		List workProducts = new ArrayList();
		List activities = new ArrayList();
		for (Iterator iter = activity.getBreakdownElements().iterator(); iter
				.hasNext();) {
			Object element = iter.next();
			if (element instanceof Descriptor) {
				if (((Descriptor) element).getIsSynchronizedWithSource()
						.booleanValue()
						&& !deleteList.contains(element)) {
					if (element instanceof TaskDescriptor) {
						Task task = ((TaskDescriptor) element).getTask();
						if (task != null) {
							tasks.add(task);
						}
					} else if (element instanceof RoleDescriptor) {
						Role role = ((RoleDescriptor) element).getRole();
						if (role != null) {
							roles.add(role);
						}
					} else if (element instanceof WorkProductDescriptor) {
						WorkProduct wp = ((WorkProductDescriptor) element)
								.getWorkProduct();
						if (wp != null) {
							workProducts.add(wp);
						}
					}
				}
			} else if (element instanceof Activity) {
				activities.add(element);
			} else if (element instanceof TeamProfile) {
				appendCommands((TeamProfile)element);
			}
		}
		if (!tasks.isEmpty()) {
			append(new WBSDropCommand(activity, tasks, config, synchFeatures));
		}
		if (!roles.isEmpty()) {
			append(new OBSDropCommand(activity, roles, config, synchFeatures, configurator));
		}
		if (!workProducts.isEmpty()) {
			append(new PBSDropCommand(activity, workProducts, config,
					synchFeatures, configurator));
		}
		for (Iterator iter = activities.iterator(); iter.hasNext();) {
			appendCommands((Activity) iter.next());
		}
	}
	
	private void appendCommands(TeamProfile team) {
		Iterator iter = new AbstractTreeIterator(team, false) {

			/**
			 * 
			 */
			private static final long serialVersionUID = 1L;

			protected Iterator getChildren(Object object) {
				if(object instanceof TeamProfile) {
					TeamProfile team = ((TeamProfile)object);
					List children = new ArrayList(team.getSubTeam());
					children.addAll(team.getTeamRoles());
					return children.iterator();
				}
				else {
					return Collections.EMPTY_LIST.iterator();
				}
			}
			
		};
		while(iter.hasNext()) {
			Object obj = iter.next();
			
			// synch only own role descriptor of team profile
			//
			if(obj instanceof RoleDescriptor && ((RoleDescriptor)obj).getSuperActivities() == null) {
				append(new BasicSynchronizeDescriptorCommand((Descriptor) obj, synchFeatures, config));
			}
		}
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.command.IResourceAwareCommand#getModifiedResources()
	 */
	public Collection getModifiedResources() {
		HashSet modifiedResources = new HashSet();
		for (Iterator iter = commandList.iterator(); iter.hasNext();) {
			IResourceAwareCommand cmd = (IResourceAwareCommand) iter.next();
			modifiedResources.addAll(cmd.getModifiedResources());
		}
		return modifiedResources;
	}
	
//	public void setUIContext(Object UIContext) {
//		this.UIContext = UIContext;
//	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.common.command.CompoundCommand#execute()
	 */
	public void execute() {
		// delete all descriptors whose linked element are no longer in the
		// configuration
		//
		if (!deleteList.isEmpty()) {
			Command cmd = delete(deleteList);
			if (cmd != null) {
				deleteCommandList.add(cmd);
			}
		}

		if (!aborted) {
//			IRunnableWithProgress runnable = new IRunnableWithProgress() {
//
//				public void run(IProgressMonitor monitor)
//						throws InvocationTargetException, InterruptedException {
//					preExecSuccessful = preExecute();
//				}
//
//			};
//						
//			UserInteractionHelper.runWithProgress(runnable, false, null);
//
//			if (preExecSuccessful) {
//				try {
//					BusyIndicator.showWhile(Display.getCurrent(), new Runnable() {
//						
//						public void run() {
//							superRedo();
//							successful = true;
//						}
//						
//					});
//				}
//				catch(RuntimeException e) {
//					LibraryEditPlugin.getDefault().getMsgDialog().displayError(getLabel(), e.toString());
//				}
//			}
			
			Runnable runnable = new Runnable() {

				public void run() {
					preExecSuccessful = preExecute();
					if(preExecute()) {
						superRedo();
						successful = true;
					}
				}

			};
			UserInteractionHelper.runInUI(runnable, getLabel());
			
			if (successful) {				
				if(!activities.isEmpty()) {
					if(deleteUnusedDescriptorsCommand == null) {
						deleteUnusedDescriptorsCommand = new DeleteUnusedDescriptorsCommand(elements, true, deleteList) {
							
							protected Command delete(List elements) {
								return SynchronizeCommand.this.delete(elements);
							}
							
						};
						deleteCommandList.add(deleteUnusedDescriptorsCommand);
					}
					deleteUnusedDescriptorsCommand.execute();
				}
				
				if (showSuccessfulMsg) {
					Messenger.INSTANCE.showInfo(
									LibraryEditResources.SynchronizeCompleteDialog_Title,
									LibraryEditResources.AutoSynchronizeCommand_sucessful);
				}
			}
		}
	}

	private void superRedo() {
		super.redo();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.common.command.CompoundCommand#redo()
	 */
	public void redo() {
		execute();
	}

	public boolean isSucessful() {
		return successful;
	}

	protected boolean preExecute() {
		for (ListIterator commands = commandList.listIterator(); commands
				.hasNext();) {
			Object command = commands.next();
			if(command instanceof BSDropCommand && !((BSDropCommand)command).preExecute()) {
				return false;
			}
			
			// be polite to other threads (no effect on some platforms)
			//
			Thread.yield();
		}
		return true;
	}

	/**
	 * Deletes the specified elements
	 * @param elements
	 * @return the executed command that deleted the given elements
	 */
	protected Command delete(List elements) {
		EditingDomain domain = new AdapterFactoryEditingDomain(
				TngAdapterFactory.INSTANCE.getProcessComposedAdapterFactory(),
				new BasicCommandStack());
		Command cmd = new ProcessElementDeleteCommand(RemoveCommand.create(domain,
				elements), elements);
		cmd.execute();
		return cmd;
	}

	private IConfigurator getConfigurator() {
		if (configurator == null) {
			MethodConfiguration config = this.config;
			if(config == null) {
				Process proc = TngUtil.getOwningProcess((BreakdownElement) elements
						.iterator().next());
				config = proc.getDefaultContext();
			}
			configurator = Providers.getConfiguratorFactory()
					.createConfigurator(config);
		}
		return configurator;
	}

	/**
	 * @param element
	 * @param deleteList
	 */
	private void addToDeleteList(Object element, List deleteList) {
		if (element instanceof Descriptor) {
			if (!getConfigurator().accept(element)) {
				deleteList.add(element);
			}
		} else if (element instanceof Activity) {
			for (Iterator iter = ((Activity) element).getBreakdownElements()
					.iterator(); iter.hasNext();) {
				addToDeleteList(iter.next(), deleteList);
			}
		}
	}

	private void superUndo() {
		super.undo();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.common.command.CompoundCommand#undo()
	 */
	public void undo() {
		BusyIndicator.showWhile(Display.getCurrent(), new Runnable() {

			public void run() {
				if (!deleteCommandList.isEmpty()) {
					for (ListIterator commands = deleteCommandList
							.listIterator(deleteCommandList.size()); commands
							.hasPrevious();) {
						try {
							Command command = (Command) commands.previous();
							command.undo();
						} catch (RuntimeException exception) {
							// Skip over the command that threw the exception.
							//
							commands.next();

							try {
								// Iterate forward over the undone commands to
								// redo them.
								//
								while (commands.hasNext()) {
									Command command = (Command) commands.next();
									command.redo();
								}
							} catch (RuntimeException nestedException) {
								CommonPlugin.INSTANCE
										.log(new WrappedException(
												CommonPlugin.INSTANCE
														.getString("_UI_IgnoreException_exception"), nestedException).fillInStackTrace()); //$NON-NLS-1$
							}

							throw exception;
						}
					}
				}

				superUndo();
			}

		});
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.common.command.CompoundCommand#prepare()
	 */
	protected boolean prepare() {
		return true;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.emf.common.command.CompoundCommand#dispose()
	 */
	public void dispose() {
		if(activities != null) {
			activities.clear();
		}
		if(deleteCommandList != null) {
			for (Iterator iter = deleteCommandList.iterator(); iter.hasNext();) {
				Command cmd = (Command) iter.next();
				cmd.dispose();
			}
		}
		if(deleteList != null) {
			deleteList.clear();
		}
		
		super.dispose();
	}
}
