//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 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.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.emf.common.util.AbstractTreeIterator;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.epf.library.edit.IConfigurator;
import org.eclipse.epf.library.edit.Providers;
import org.eclipse.epf.library.edit.command.BatchCommand;
import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.edit.validation.UniqueNamePNameHandler;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.Artifact;
import org.eclipse.epf.uma.Deliverable;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.ProcessPackage;
import org.eclipse.epf.uma.RoleDescriptor;
import org.eclipse.epf.uma.Task;
import org.eclipse.epf.uma.TaskDescriptor;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.WorkProduct;
import org.eclipse.epf.uma.WorkProductDescriptor;


/**
 * Command to drag and drop work products to Work Product Usage breakdown
 * structure
 * 
 * @author Phong Nguyen Le
 * @author Shilpa Toraskar
 * @since 1.0
 */
public class PBSDropCommand extends BSDropCommand {
	private ArrayList wpDescList;

	private ArrayList roleDescList;

	private Map wpDescToDeliverableParts;

	private HashMap<WorkProductDescriptor, WorkProductDescriptor> wpdToDeliverableDescriptorMap;

	private BatchCommand updateDeliverablePartsCmd;

	private boolean newDuplicatesRemoved;

	private IConfigurator configurator;

	private ArrayList linkedTasks;

	private HashMap wpdToTaskFeaturesMap;

	public PBSDropCommand(Activity activity, List workProducts) {
		super(activity, workProducts);
		this.activity = activity;
		for (Iterator iter = dropElements.iterator(); iter.hasNext();) {
			Object element = iter.next();
			if (!(element instanceof WorkProduct)) {
				iter.remove();
			}
		}
	}

	/**
	 * @param activity
	 * @param dropElements
	 * @param synch
	 */
	public PBSDropCommand(Activity activity, List dropElements, boolean synch) {
		super(activity, dropElements, synch);
	}

	/**
	 * @param activity
	 * @param dropElements
	 * @param config
	 * @param synchFeatures
	 */
	public PBSDropCommand(Activity activity, List dropElements,
			MethodConfiguration config, Set synchFeatures, IConfigurator configurator) {
		super(activity, dropElements, config, synchFeatures);
		this.configurator = configurator;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.process.command.BSDropCommand#preExecute()
	 */
	protected boolean preExecute() {
		if (!super.preExecute())
			return false;

		wpDescList = new ArrayList();
		taskDescList = new ArrayList();
		roleDescList = new ArrayList();
		wpDescToDeliverableParts = new HashMap();
		wpdToDeliverableDescriptorMap = new HashMap();

		if(!synchronize || (synchronize && synchFeatures.contains(UmaPackage.eINSTANCE.getArtifact_ContainedArtifacts()))) {
			// add subartifacts to dropElements list if there is any
			//
			for (Iterator iter = new ArrayList(dropElements).iterator(); iter
			.hasNext();) {
				Object element = iter.next();
				if (element instanceof Artifact) {
					Iterator iterator = new AbstractTreeIterator(element, false) {
						
						/**
						 * Comment for <code>serialVersionUID</code>
						 */
						private static final long serialVersionUID = -4820477887426087262L;
						
						protected Iterator getChildren(Object object) {
							Object subArtifacts = Providers.getConfigurationApplicator().getReference(
									(VariabilityElement) object,
									UmaPackage.eINSTANCE.getArtifact_ContainedArtifacts(),
									getMethodConfiguration());
							return ((Collection)subArtifacts).iterator();
						}
						
					};
					
					while (iterator.hasNext()) {
						Artifact subArtifact = (Artifact) iterator.next();
						if (!dropElements.contains(subArtifact) && prepareAdd((WorkProduct) subArtifact)) 
						{
							dropElements.add(subArtifact);
						}
					}
				}
			}
		}

		MethodConfiguration config = getMethodConfiguration();
		Set descriptorsToRefresh = synchronize ? batchCommand.getDescriptorsToRefresh() : null;
		
		List bes = activity.getBreakdownElements();
		UniqueNamePNameHandler uniqueNamesHandler = new UniqueNamePNameHandler(bes);
		
		for (int i = 0; i < dropElements.size(); i++) {
			WorkProduct wp = (WorkProduct) dropElements.get(i);			
			if (TngUtil.isContributor(wp)) {
				wp = (WorkProduct) TngUtil.getBase(wp);
			}
			WorkProductDescriptor wpDesc = null;
			if (synchronize) {
				wpDesc = (WorkProductDescriptor) ProcessCommandUtil
					.getDescriptor(wp, activity, config);
			}
			if (wpDesc == null) {
				wpDesc = ProcessCommandUtil.createWorkProductDescriptor(wp, config,
						wpDescToDeliverableParts);
//				uniqueNamesHandler.ensureUnique(wpDesc);
				wpDescList.add(wpDesc);

				// automatic adding to the existing deliverable descriptor in
				// the activity's scope if there is any
				// valid one.
				//
				WorkProductDescriptor descriptor = UserInteractionHelper
						.getDeliverable(activity, wp);
				if (descriptor != null) {
					wpdToDeliverableDescriptorMap.put(wpDesc, descriptor);
				}
				
				if(wpdToTaskFeaturesMap != null) {
					// replace work product with its work product descriptor in wpdToTaskFeaturesMap
					//
					Map featuresMap = (Map) wpdToTaskFeaturesMap.get(wp);
					if(featuresMap != null) {
						wpdToTaskFeaturesMap.remove(wp);
						wpdToTaskFeaturesMap.put(wpDesc, featuresMap);
					}
				}

			} else {
				if (descriptorsToRefresh != null && wpDesc.getIsSynchronizedWithSource().booleanValue()) {
					descriptorsToRefresh.add(wpDesc);
				}
				if (wp instanceof Deliverable && synchFeatures.contains(UmaPackage.eINSTANCE.getDeliverable_DeliveredWorkProducts())) {
					ProcessCommandUtil.createDeliverableParts(wpDesc,
							(Deliverable) wp, config, wpDescToDeliverableParts, descriptorsToRefresh);
				}
				
				if(wpdToTaskFeaturesMap != null) {
					wpdToTaskFeaturesMap.remove(wp);
				}
			}

		
			if (!synchronize) {
				// get all possible tasks for this workproduct for
				// which task descriptor needs to be created
				List tasks = ProcessUtil.getTasksForWorkProduct(wp, config);

				if ((tasks != null) && (tasks.size() > 0)) {
					// show task selections dialog		
					final List finalTasks = tasks;
					final WorkProduct finalWp = wp;
					final List finalSelected = new ArrayList();
					List selectedTasks = new ArrayList();
					// show task selections dialog
					UserInteractionHelper.getUIHelper().runSafely(new Runnable() {
						public void run() {
							List selected = UserInteractionHelper.selectTasks(
									finalTasks, finalWp);						
							finalSelected.addAll(selected);
						}
					}, true);
					selectedTasks.addAll(finalSelected);
					
					// create task descriptors for this workproduct
					if ((selectedTasks != null) && (!(selectedTasks.isEmpty()))) {
						for (int j = 0; j < selectedTasks.size(); j++) {
							Task task = (Task) selectedTasks.get(j);

							// call this method even the descriptor for the
							// given task already exists in this activity
							// to add any additional relationships in case of
							// recent change in the default configuration
							// of the process.
							PBSDropCommand.addToDescriptorLists(task, activity,
									taskDescList, roleDescList, wpDescList,
									wpDescToDeliverableParts,
									descriptorsToRefresh,
									batchCommand.getObjectToNewFeatureValuesMap(), 
									config, true, synchFeatures);
						}
					} else {
						// If no tasks are selected, add Responsible role to wp
						ProcessCommandUtil.addResponsibleRoleDescriptors(wpDesc, activity,
								roleDescList, descriptorsToRefresh, config);
					}
				}
				else {
					//	If there are no tasks to show, add Responsible role to wp
					ProcessCommandUtil.addResponsibleRoleDescriptors(wpDesc, activity,	roleDescList, descriptorsToRefresh, config);
				}
			}
//			else {
//				//	in case of synchronization, add Responsible role to wp
//				if (synchFeatures.contains(UmaPackage.eINSTANCE.getRole_ResponsibleFor()))
//					PBSDropCommand.addResponsibleRole(wpDesc, activity,	roleDescList, descriptorsToRefresh, config);
//			}				
		}

		if(!wpDescToDeliverableParts.isEmpty()) {
			updateDeliverablePartsCmd = new BatchCommand(true);
			for (Iterator iter = wpDescToDeliverableParts.entrySet().iterator(); iter
			.hasNext();) {
				Map.Entry entry = (Map.Entry) iter.next();
				Object wpDesc = entry.getKey();
				updateDeliverablePartsCmd.getObjectToNewFeatureValuesMap().put(wpDesc, 
						Collections.singletonMap(UmaPackage.eINSTANCE.getWorkProductDescriptor_DeliverableParts(), entry.getValue()));
			}
		}
		

		// ensure unique names for wp descriptors
		for (int i = 0; i < wpDescList.size(); i++) {
			WorkProductDescriptor wpDesc = (WorkProductDescriptor) wpDescList
					.get(i);
			if (wpDesc != null) {
				uniqueNamesHandler.ensureUnique(wpDesc);
			}
		}
		return !taskDescList.isEmpty()
				|| !roleDescList.isEmpty()
				|| !wpDescList.isEmpty()
				|| (updateDeliverablePartsCmd != null && updateDeliverablePartsCmd.canExecute())
				|| !wpdToDeliverableDescriptorMap.isEmpty()
				|| (descriptorsToRefresh != null && !descriptorsToRefresh
						.isEmpty())
				|| batchCommand.canExecute();
	}
	
	/**
	 * @param subArtifact
	 * @return
	 */
	private boolean prepareAdd(WorkProduct wp) {
		if (synchronize) {	
			// get linked tasks of the task descriptors in the activity for the configuration
			//
			List tasks = getLinkedTasks();
			
			if(!tasks.isEmpty()) {
				// select only work products that are input or output of an existing task in the activity
				//	
				Map featuresMap = ProcessCommandUtil.getFeaturesMap(tasks, wp, getMethodConfiguration());
				if(!featuresMap.isEmpty()) {
					// use the wp to the key in the map right now and replace it with
					// its work product descriptor later
					//
					if(wpdToTaskFeaturesMap == null) {
						wpdToTaskFeaturesMap = new HashMap();
					}
					wpdToTaskFeaturesMap.put(wp, featuresMap);
					return true;
				}
			}
			return false;
		}
		return true;
	}

	/**
	 * @return
	 */
	private List getLinkedTasks() {
		if(linkedTasks == null) {
			linkedTasks = new ArrayList();
			for (Iterator iter = activity.getBreakdownElements().iterator(); iter.hasNext();) {
				Object element = iter.next();
				if(element instanceof TaskDescriptor) {
					Task task = ((TaskDescriptor)element).getTask();
					if(task != null && configurator.accept(element)) {
						linkedTasks.add(task);
					}
				}
			}
		}
		return linkedTasks;
	}

	/**
	 * Removes new elements that are duplicate b/c they are created by the previous WBSDropCommand
	 */
	private void removeNewDuplicates() {
		if(synchronize) {
			if(!newDuplicatesRemoved) {
				for (Iterator iter = roleDescList.iterator(); iter.hasNext();) {
					RoleDescriptor roleDesc = (RoleDescriptor) iter.next();
					Object desc = ProcessCommandUtil.getDescriptor(roleDesc.getRole(), activity, getMethodConfiguration());
					if(desc != null) {
						iter.remove();
					}
				}
				newDuplicatesRemoved = true;			
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.process.command.BSDropCommand#doExecute()
	 */
	protected void doExecute() {
		removeNewDuplicates();
		
		// automatically add work product descriptor to deliverable part
		//
		if (!wpdToDeliverableDescriptorMap.isEmpty()) {
			for (Map.Entry<WorkProductDescriptor, WorkProductDescriptor> entry : 
				wpdToDeliverableDescriptorMap.entrySet()) {
				WorkProductDescriptor deliverable = (WorkProductDescriptor) entry
						.getValue();
				deliverable.getDeliverableParts().add(entry.getKey());
			}
		}

		// add work product descriptors
		//
		activity.getBreakdownElements().addAll(wpDescList);

		// add task descriptors
		//
		activity.getBreakdownElements().addAll(taskDescList);

		// add role descriptors
		//
		activity.getBreakdownElements().addAll(roleDescList);
		
		// associate new work product descriptors with task descriptors
		//
		if(wpdToTaskFeaturesMap != null) {
			for (Iterator iter = wpdToTaskFeaturesMap.entrySet().iterator(); iter.hasNext();) {
				Map.Entry entry = (Map.Entry) iter.next();
				Map taskFeatures = (Map) entry.getValue();
				for (Iterator iterator = taskFeatures.entrySet().iterator(); iterator
				.hasNext();) {
					Map.Entry ent = (Map.Entry) iterator.next();
					TaskDescriptor taskDesc = (TaskDescriptor) ProcessCommandUtil.getDescriptor(ent.getKey(), activity.getBreakdownElements(), getMethodConfiguration(), false);
					for (Iterator iterator1 = ((Collection)ent.getValue()).iterator(); iterator1
					.hasNext();) {
						EStructuralFeature f = (EStructuralFeature) iterator1.next();
						EStructuralFeature descFeature = (EStructuralFeature) FEATURE_MAP.get(f);
						if(descFeature.isMany()) {
							((List)taskDesc.eGet(descFeature)).add(entry.getKey());							
						}
						else {
							// TODO: need to back up old value here
							//
							taskDesc.eSet(descFeature, entry.getKey());
						}
					}
				}
			}
		}

		// add new descriptors to activity's package
		//
		ProcessPackage pkg = (ProcessPackage) activity.eContainer();
		if (pkg != null) {
			pkg.getProcessElements().addAll(taskDescList);
			pkg.getProcessElements().addAll(roleDescList);
			pkg.getProcessElements().addAll(wpDescList);

			for (Iterator iter = wpDescToDeliverableParts.values().iterator(); iter
					.hasNext();) {
				pkg.getProcessElements().addAll((Collection) iter.next());
			}
		}

//		getModifiedResources().add(activity.eResource());
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.edit.process.command.BSDropCommand#updateDescriptors()
	 */
	protected void updateDescriptors() {
		super.updateDescriptors();
		
		// add deliverable parts to the work product descriptors
		//
		if(updateDeliverablePartsCmd != null) {
			updateDeliverablePartsCmd.execute();
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.edit.process.command.BSDropCommand#undoUpdateDescriptors()
	 */
	protected void undoUpdateDescriptors() {
		// remove deliverable parts of the work product descriptors
		//
		if(updateDeliverablePartsCmd != null) {
			updateDeliverablePartsCmd.undo();
		}

		super.undoUpdateDescriptors();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.process.command.BSDropCommand#doUndo()
	 */
	protected void doUndo() {
		// remove work product descriptors
		//
		activity.getBreakdownElements().removeAll(wpDescList);

		// remove role descriptors
		//
		activity.getBreakdownElements().removeAll(roleDescList);

		// remove task descriptors
		//
		activity.getBreakdownElements().removeAll(taskDescList);

		// remove work product descriptor from deliverable part
		//
		if (!wpdToDeliverableDescriptorMap.isEmpty()) {
			for (Iterator iter = wpdToDeliverableDescriptorMap.entrySet()
					.iterator(); iter.hasNext();) {
				Map.Entry entry = (Map.Entry) iter.next();
				WorkProductDescriptor deliverable = (WorkProductDescriptor) entry
						.getValue();
				deliverable.getDeliverableParts().remove(entry.getKey());
			}
		}

		// remove descriptors from activity's package
		//
		ProcessPackage pkg = (ProcessPackage) activity.eContainer();
		if (pkg != null) {
			pkg.getProcessElements().removeAll(taskDescList);
			pkg.getProcessElements().removeAll(roleDescList);
			pkg.getProcessElements().removeAll(wpDescList);
			for (Iterator iter = wpDescToDeliverableParts.values().iterator(); iter
					.hasNext();) {
				pkg.getProcessElements().removeAll((Collection) iter.next());
			}
		}
		
		// disassociate new work product descriptors with task descriptors
		//
		if(wpdToTaskFeaturesMap != null) {
			for (Iterator iter = wpdToTaskFeaturesMap.entrySet().iterator(); iter.hasNext();) {
				Map.Entry entry = (Map.Entry) iter.next();
				Map taskFeatures = (Map) entry.getValue();
				for (Iterator iterator = taskFeatures.entrySet().iterator(); iterator
						.hasNext();) {
					Map.Entry ent = (Map.Entry) iterator.next();
					TaskDescriptor taskDesc = (TaskDescriptor) ProcessCommandUtil.getDescriptor(ent.getKey(), activity, getMethodConfiguration());
					for (Iterator iterator1 = ((Collection)ent.getValue()).iterator(); iterator1
							.hasNext();) {
						EStructuralFeature f = (EStructuralFeature) iterator1.next();
						EStructuralFeature descFeature = (EStructuralFeature) FEATURE_MAP.get(f);
						if(descFeature.isMany()) {
							((List)taskDesc.eGet(descFeature)).remove(entry.getKey());							
						}
						else {
							taskDesc.eSet(descFeature, null);
						}
					}
				}
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.common.command.AbstractCommand#getAffectedObjects()
	 */
	public Collection getAffectedObjects() {
		if (wpDescList != null) {
			return wpDescList;
		}

		return super.getAffectedObjects();
	}

	/**
	 * 
	 * @param task
	 * @param activity
	 * @param taskDescList
	 * @param roleDescList
	 * @param wpDescList
	 * @param wpDescToDeliverableParts
	 * @param descriptorsToRefresh
	 * @return <code>true</code> if a new TaskDescriptor is created for the
	 *         given task, <code>false</code> otherwise
	 */
	static boolean addToDescriptorLists(Task task, Activity activity,
			List taskDescList, List roleDescList, List wpDescList,
			Map wpDescToDeliverableParts, Set descriptorsToRefresh,
			Map descriptorToNewFeatureValuesMap, MethodConfiguration config, boolean useExistingDescriptor, Set synchFeatures) {
		TaskDescriptor desc = ProcessCommandUtil.createTaskDescriptor(task, activity,
				roleDescList, wpDescList, wpDescToDeliverableParts, null,
				descriptorsToRefresh, descriptorToNewFeatureValuesMap, 
				config, useExistingDescriptor, synchFeatures);
		if ((desc != null) && (taskDescList != null)
				&& !taskDescList.contains(desc)) {
			taskDescList.add(desc);
		}
		return desc != null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.edit.process.command.BSDropCommand#dispose()
	 */
	public void dispose() {
		if(roleDescList != null) {
			roleDescList.clear();
		}
		if(wpDescList != null) {
			wpDescList.clear();
		}
		if(wpDescToDeliverableParts != null) {
			wpDescToDeliverableParts.clear();
		}
		if(wpdToDeliverableDescriptorMap != null) {
			wpdToDeliverableDescriptorMap.clear();
		}
		if(wpdToTaskFeaturesMap != null) {
			wpdToTaskFeaturesMap.clear();
		}
		
		super.dispose();
	}
	
}
