//------------------------------------------------------------------------------
// 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.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
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.notify.AdapterFactory;
import org.eclipse.emf.common.util.AbstractTreeIterator;
import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.emf.ecore.EObject;
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.LibraryEditResources;
import org.eclipse.epf.library.edit.Providers;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.command.BatchCommand;
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.ProcessUtil;
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.MethodElement;
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.VariabilityElement;
import org.eclipse.epf.uma.WorkProduct;
import org.eclipse.epf.uma.WorkProductDescriptor;


/**
 * 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 BatchCommand batchCommand = new BatchCommand(false);
	private Map<VariabilityElement, VariabilityElement> replacerToBaseMap = new HashMap<VariabilityElement, VariabilityElement>();  

//	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() {
		commandList.clear();
		
		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) {
								if(replacerToBaseMap.containsKey(task)) {
									task = (Task) replacerToBaseMap.get(task);
								}
								append(new WBSDropCommand(act, Collections
										.singletonList(task), config, synchFeatures));
							}
						} else if (object instanceof RoleDescriptor) {
							Role role = ((RoleDescriptor) object).getRole();
							if (role != null) {
								if(replacerToBaseMap.containsKey(role)) {
									role = (Role) replacerToBaseMap.get(role);
								}
								append(new OBSDropCommand(act, Collections
										.singletonList(role), config, synchFeatures, configurator));
							}
						} else if (object instanceof WorkProductDescriptor) {
							WorkProduct wp = ((WorkProductDescriptor) object)
							.getWorkProduct();
							if (wp != null) {
								if(replacerToBaseMap.containsKey(wp)) {
									wp = (WorkProduct) replacerToBaseMap.get(wp);
								}
								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() {
		boolean b = isPrepared;
		try {
			// since Eclipse 3.3, CompoundCommand.append() throws IllegalStateException if isPrepared is already set
			// but this method is called after isPrepared is set in canExecute() and it makes many calls to append()
			// work-around is to unset isPrepared at beginning of this method and set it back to old value at method end.
			//
			isPrepared = false;
			return intialized = doInitialize();		
		}
		finally {
			isPrepared = b;
		}
	}
	
	/**
	 * @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) {
							if(replacerToBaseMap.containsKey(task)) {
								task = (Task) replacerToBaseMap.get(task);
							}
							tasks.add(task);
						}
					} else if (element instanceof RoleDescriptor) {
						Role role = ((RoleDescriptor) element).getRole();
						if (role != null) {
							if(replacerToBaseMap.containsKey(role)) {
								role = (Role) replacerToBaseMap.get(role);
							}
							roles.add(role);
						}
					} else if (element instanceof WorkProductDescriptor) {
						WorkProduct wp = ((WorkProductDescriptor) element)
								.getWorkProduct();
						if (wp != null) {
							if(replacerToBaseMap.containsKey(wp)) {
								wp = (WorkProduct) replacerToBaseMap.get(wp);
							}
							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();) {
			
			Object cmd = iter.next();
			if(cmd instanceof IResourceAwareCommand) {
				modifiedResources.addAll(((IResourceAwareCommand)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);
			}
		}
		
		batchCommand.execute();
		
		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) {
					if(!replacerToBaseMap.isEmpty()) {
						refreshViewer();
					}
					Messenger.INSTANCE.showInfo(
									LibraryEditResources.SynchronizeCompleteDialog_Title,
									LibraryEditResources.AutoSynchronizeCommand_sucessful);
				}
			}
		}
	}

	private void refreshViewer() {
		if(elements.isEmpty())  return;
		Process proc = TngUtil.getOwningProcess(elements.iterator().next());
		if(proc != null) {
			for (int i = 0; i < TngAdapterFactory.processAdapterFactories.length; i++) {
				AdapterFactory adapterFactory = TngAdapterFactory.processAdapterFactories[i];
				ProcessUtil.refreshViewer(adapterFactory, proc);
			}
		}
	}

	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)) {
				MethodElement linkedElement = ProcessUtil.getAssociatedElement((Descriptor) element);				
				if(linkedElement instanceof VariabilityElement && TngUtil.isReplacer((VariabilityElement) linkedElement)) {
					// if the linked element of the descriptor is a replacer, delete the descriptor in this synchronization
					// only if the base of linked element is not in the configuration
					//
					VariabilityElement base = ((VariabilityElement)linkedElement).getVariabilityBasedOnElement();
					while(base != null && TngUtil.isContributorOrReplacer(base)) {
						base = base.getVariabilityBasedOnElement();
					}
					if(base != null) {
						if(!getConfigurator().accept(base)) {
							deleteList.add(element);
						}
						else {
							batchCommand.addFeatureValue((EObject) element, 
									ProcessUtil.getLinkReference((Descriptor) element), base);
							replacerToBaseMap.put((VariabilityElement) linkedElement, base);
						}
					}
				}
				else {
					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() {
		UserInteractionHelper.getUIHelper().runWithBusyIndicator(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();
				
				batchCommand.undo();
			}

		});
	}

	/*
	 * (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();
	}
}
