//------------------------------------------------------------------------------
// 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.lang.reflect.InvocationTargetException;
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 org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.util.AbstractTreeIterator;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
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.TngAdapterFactory;
import org.eclipse.epf.library.edit.ui.IActionTypeProvider;
import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
import org.eclipse.epf.library.edit.util.ActivityHandler;
import org.eclipse.epf.library.edit.util.IRunnableWithProgress;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.Suppression;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.edit.validation.DependencyChecker;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.CapabilityPattern;
import org.eclipse.epf.uma.DeliveryProcess;
import org.eclipse.epf.uma.DescribableElement;
import org.eclipse.epf.uma.Descriptor;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodPackage;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessPackage;
import org.eclipse.epf.uma.TeamProfile;


/**
 * Drop command for activity that supports extend, copy, and deep copy.
 * 
 * @author Phong Nguyen Le
 * @since 1.0
 */
public class ActivityDropCommand extends BSDropCommand {

	private Object viewer;

	private List<CapabilityPattern> oldPatterns;

	private List<CapabilityPattern> patterns;

	protected Process targetProcess;

	private boolean isDeliveryProcess;

	private int type;
	
	private Collection<Activity> appliedActivities;

	protected AdapterFactory adapterFactory;

	protected ActivityHandler activityHandler;

	protected boolean preExecuted;

	protected HashSet<?> addedObjects;
	
	protected IConfigurator activityDeepCopyConfigurator;

	public ActivityDropCommand(Activity target, List activities, Object viewer, AdapterFactory adapterFactory) {
		super(target, activities);
		setLabel(LibraryEditResources.ActivityDropCommand_label); 
		this.viewer = viewer;
		this.adapterFactory = adapterFactory;
		targetProcess = TngUtil.getOwningProcess(target);
		
		isDeliveryProcess = targetProcess instanceof DeliveryProcess;
		if (isDeliveryProcess) {
			oldPatterns = new ArrayList(((DeliveryProcess) targetProcess)
					.getIncludesPatterns());
		}
	}
	
	public ActivityDropCommand(Activity target, List activities, Object viewer, 
			AdapterFactory adapterFactory,IConfigurator deepCopyConfigurator){
		this(target, activities, viewer, adapterFactory);
		this.activityDeepCopyConfigurator = deepCopyConfigurator;
	}
	
	@Override
	protected void prepareDropElements() {
		// remove any drop element that is suppress
		//
		for (Iterator<?> iter = dropElements.iterator(); iter.hasNext();) {
			Object element = (Object) iter.next();
			Process proc = TngUtil.getOwningProcess(element);
			if(proc != null) {
				Suppression supp = Suppression.getSuppression(proc);
				if(supp.isSuppressed(element)) {
					iter.remove();
				}
			}
		}

		super.prepareDropElements();		
	}
	
	public void setType(int type) {
		this.type = type;
		if(type == IActionTypeProvider.DEEP_COPY) {
			runAsJob = true;
		}
	}
	
	public IStatus checkCopy() {
		for (Object e : dropElements) {
			if(e instanceof Activity) {
				IStatus status = checkCircular((Activity) e);
				if(!status.isOK()) {
					return status;
				}
			}
		}
		return Status.OK_STATUS;
	}
	
	public IStatus checkExtend() {
		for (Iterator iter = dropElements.iterator(); iter.hasNext();) {
//			BreakdownElement element = (BreakdownElement) iter.next();
//			
//			if ((ProcessUtil.hasContributorOrReplacer((Activity) element))){
//				canExtend = false;
//				break;
//			}
//			
//			Process proc = TngUtil.getOwningProcess(element);
//			if (targetProcess.getVariabilityBasedOnElement() == proc) {
//				canExtend = false;
//				break;
//			}
//			
//			if (proc instanceof CapabilityPattern && proc != targetProcess) {
//				canExtend = true;
//				break;
//			}
			
			Activity act = (Activity) iter.next();
			Process srcProc = TngUtil.getOwningProcess(act);
			if(srcProc instanceof DeliveryProcess && srcProc != targetProcess) {
				// cannot extend a different delivery process or any of its activities
				//
				return new Status(IStatus.ERROR, LibraryEditPlugin.PLUGIN_ID, 0,
						LibraryEditResources.cannot_copy_or_extend_delivery_process,
						null);
			}
			IStatus status = checkCircular(act);
			if(!status.isOK()) {
				return status;
			}
		}
		return Status.OK_STATUS;
	}
	
	private IStatus checkCircular(Activity act) {
		boolean result;
		if (DependencyChecker.newCheckAct) {
			result = DependencyChecker.checkCircularForMovingVariabilityElement
							(activity, Collections.singletonList(act), true);
		} else {
			result = DependencyChecker.checkCircularDependency(act, activity).isOK();
		}
		if(!result) {
			return new Status(IStatus.ERROR, LibraryEditPlugin.PLUGIN_ID, 0,
					LibraryEditResources.circular_dependency_error_msg,
					null);
		}
		return Status.OK_STATUS;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.process.command.BSDropCommand#execute()
	 */
	public void execute() {
		IActionTypeProvider actionTypeProvider = (IActionTypeProvider) viewer;
		if ( viewer != null) {
			viewer = null;
			boolean canCopy = checkCopy().isOK();
			boolean canExtend = checkExtend().isOK();
			int[] choices = new int[1 + (canCopy ? 1 : 0) + (canExtend ? 1 : 0)];
			int i = 0;
			if(canCopy) {
				choices[i++] = IActionTypeProvider.COPY;
			}
			if(canExtend) {
				choices[i++] = IActionTypeProvider.EXTEND;
			}
			choices[i] = IActionTypeProvider.DEEP_COPY;
			
			// delegate the execution of this command
			//
			actionTypeProvider.execute(this, choices);

			return;
		}

		activityHandler = new ActivityHandler();
		try {
			if (type == IActionTypeProvider.DEEP_COPY) {
				doDeepCopy();
			} else {
				super.execute();
			}
		} finally {
			activityHandler.dispose();
		}
		
		if(TngUtil.DEBUG) {
			System.out.println("ActivityDropCommand.execute(): done");
		}
	}

	/**
	 * 
	 */
	protected void doDeepCopy() {
		if(!UserInteractionHelper.confirmDeepCopy(dropElements)) {
			return;
		}
		MethodConfiguration deepCopyConfig = null;
		try {
			deepCopyConfig = UserInteractionHelper.chooseDeepCopyConfiguration(targetProcess, adapterFactory);
		}
		catch(OperationCanceledException e) {
			getModifiedResources().clear();
			return;
		}
		
		boolean copyExternalVariations;
		try {
			copyExternalVariations = UserInteractionHelper.copyExternalVariationsAllowed(targetProcess, adapterFactory);
		}
		catch(OperationCanceledException e) {
			getModifiedResources().clear();
			return;			
		}
		activityHandler.setCopyExternalVariations(copyExternalVariations);
		activityHandler.setDeepCopyConfig(deepCopyConfig);
		activityHandler.setTargetProcess(targetProcess);
		
		// Set a configurator to resolve and deep copy contributors and replacers
		activityHandler.setActivityDeepCopyConfigurator(activityDeepCopyConfigurator);
		
		IRunnableWithProgress runnable = new IRunnableWithProgress() {

			public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
				activityHandler.setMonitor(monitor);
				preExecuted = preExecute();
			}
			
		};
		UserInteractionHelper.runWithProgress(runnable, getLabel());			
		if (preExecuted) {
			redo();
		}
	}

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

		// process the selected activities and deep-copy the valid ones
		//
		if (isDeliveryProcess) {
			patterns = new ArrayList<CapabilityPattern>();
		}
		
		for (Iterator iter = dropElements.iterator(); iter.hasNext();) {
			Object element = (Object) iter.next();
			if ((element instanceof Activity)
			// && element != target
			) {
				Activity act = (Activity) element;
				
//				if(type == IActionTypeProvider.DEEP_COPY) {
//					activityHandler.deepCopy(act);
//				}
//				else {
//					Process proc = TngUtil.getOwningProcess(act);
//					if (proc instanceof CapabilityPattern && proc != targetProcess) {
//						if (type == IActionTypeProvider.EXTEND) {
//							activityHandler.extend(act);
//							if (patterns != null)
//								patterns.add(proc);
//						} else {
//							activityHandler.copy(act);
//						}
//					} else {
//						activityHandler.copy(act);
//					}
//				}
				
				switch(type) {
				case IActionTypeProvider.DEEP_COPY:
					activityHandler.deepCopy(element);
					break;
				case IActionTypeProvider.EXTEND:
					activityHandler.extend(act);
					if (patterns != null) {
						Process proc = TngUtil.getOwningProcess(act);
						if(proc instanceof CapabilityPattern) {
							patterns.add((CapabilityPattern) proc);
						}
					}
					break;
				case IActionTypeProvider.COPY:
					activityHandler.copy(act);
					break;
				}
			}
		}

		appliedActivities = new ArrayList<Activity>(activityHandler.getActivities());

		return !appliedActivities.isEmpty();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.process.command.BSDropCommand#doExecute()
	 */
	protected void doExecute() {
		Iterator<Activity> itor = appliedActivities.iterator();

		ProcessPackage pkg = (ProcessPackage) activity.eContainer();
		while (itor.hasNext()) {
			Activity act = (Activity) itor.next();

			if (act.eContainer() != null
					&& act.eContainer().eContainer() != pkg) {
				pkg.getChildPackages().add((MethodPackage) act.eContainer());
			}

			if (patterns != null && !patterns.isEmpty()) {
				DeliveryProcess proc = (DeliveryProcess) targetProcess;
				for (CapabilityPattern pattern : patterns) {
					if (!proc.getIncludesPatterns().contains(pattern)) {
						proc.getIncludesPatterns().add(pattern);
					}
				}
			}
		}
		long time = 0;
		if(TngUtil.DEBUG) {
			time = System.currentTimeMillis();
		}
		activity.getBreakdownElements().addAll(appliedActivities);
		if(TngUtil.DEBUG) {
			System.out.println("ActivityDropCommand.doExecute(): new activities added. " + (System.currentTimeMillis() - time));
		}
		if(!activityHandler.getDeepCopies().isEmpty()) {
			if(TngUtil.DEBUG) {
				time = System.currentTimeMillis();
			}
			postDeepCopy();
			if(TngUtil.DEBUG) {
				System.out.println("ActivityDropCommand.doExecute(): postDeepCopy(). " + (System.currentTimeMillis() - time));
			}
		}

		// Hack to refresh providers forcefully before calling fixDuplicateNames
		ITreeItemContentProvider adapter = (ITreeItemContentProvider) adapterFactory.adapt(activity, ITreeItemContentProvider.class);
		adapter.getChildren(activity);
		
		// fix duplicate names of newly added elements
		fixDuplicateNames();
		
		getModifiedResources().add(activity.eResource());
	}

	/**
	 * 
	 */
	private void postDeepCopy() {
		Runnable runnable = new Runnable() {

			public void run() {
				// add to default configuratation of the target process any missing content
				//
				if(addedObjects == null) {
					addedObjects = new HashSet();
				}
				else {
					addedObjects.clear();
				}
				boolean defaultConfigChanged = false;
//				// disable notification on change to default configuration of target process to avoid excessive UI refreshes
//				//
//				boolean oldNotify = targetProcess.getDefaultContext().eDeliver();
//				targetProcess.getDefaultContext().eSetDeliver(false);
//				try {
				for (Iterator iter = activityHandler.getDeepCopies().iterator(); iter.hasNext();) {
					Iterator iterator = new AbstractTreeIterator(iter.next()) {

						/**
						 * Comment for <code>serialVersionUID</code>
						 */
						private static final long serialVersionUID = 1L;

						protected Iterator getChildren(Object object) {
							if(object instanceof Activity) {
								return ((Activity)object).getBreakdownElements().iterator();
							}
							return Collections.EMPTY_LIST.iterator();
						}

					};					
					while(iterator.hasNext()) {
						Object e = iterator.next();
						if(e instanceof Descriptor) {
							MethodElement me = ProcessUtil.getAssociatedElement((Descriptor) e);
							int size = addedObjects.size();
							ProcessUtil.addToDefaultConfiguration(targetProcess, me, addedObjects);
							if(!defaultConfigChanged && (size != addedObjects.size())) {
								getModifiedResources().add(targetProcess.getDefaultContext().eResource());
								defaultConfigChanged = true;
							}
						}
					}
				}
//				}
//				finally {
//					targetProcess.getDefaultContext().eSetDeliver(oldNotify);
//				}
			}
			
		};
		
		UserInteractionHelper.runWithProgress(runnable, getLabel());
		
		// synchronize the deep copies with default configuration of the target process				
		//
		final SynchronizeCommand synchCmd = new SynchronizeCommand(activityHandler.getDeepCopies(), targetProcess.getDefaultContext(), null, false);
		try {
			runnable = new Runnable() {

				public void run() {
					synchCmd.initilize();
				}
				
			};
			UserInteractionHelper.runWithProgress(runnable, LibraryEditResources.ProcessAutoSynchronizeAction_prepare);
			if(synchCmd.isIntialized()) {
				synchCmd.execute();
			}
		}
		finally {
			synchCmd.dispose();
		}
	}
	
	protected Suppression getSuppression() {
		return Suppression.getSuppression(targetProcess);
	}

	/**
	 * Fixes duplicate names of newly added elements
	 */
	private void fixDuplicateNames() {
		Suppression suppression = getSuppression();
		for (Iterator iter = appliedActivities.iterator(); iter.hasNext();) {
			Activity act = (Activity) iter.next();
			fixDuplicateNames(act, suppression);
			fixTeamProfileDuplicateNames(act, suppression);
		}			
	}
	
	private void fixDuplicateNames(BreakdownElement e, Suppression suppression) {
		fixDuplicateNames(e, suppression, adapterFactory);
	}
	
	private static void fixDuplicateNames(BreakdownElement e, Suppression suppression, AdapterFactory adapterFactory) {
		String baseName = e.getName();
		if (ProcessUtil.checkBreakdownElementName(adapterFactory, e, baseName, suppression) != null) {
			for (int i = 1; true; i++) {
				String name = baseName + '_' + i;
				if (ProcessUtil.checkBreakdownElementName(adapterFactory, e, name, suppression) == null) {
					e.setName(name);
					break;
				}
			}
		}
		baseName = ProcessUtil.getPresentationName(e);
		if (ProcessUtil.checkBreakdownElementPresentationName(adapterFactory, e, baseName, suppression) != null) {
			for (int i = 1; true; i++) {
				String name = baseName + '_' + i;
				if (ProcessUtil.checkBreakdownElementPresentationName(adapterFactory, e, name, suppression) == null) {
					e.setPresentationName(name);
					break;
				}
			}
		}
	}		
	
	private void fixTeamProfileDuplicateNames(Activity act, Suppression suppression) {
		for (int i = act.getBreakdownElements().size() - 1; i > -1; i--) {
			Object element = act.getBreakdownElements().get(i);
			if(element instanceof TeamProfile) {
				fixDuplicateNames((BreakdownElement) element, suppression, TngAdapterFactory.INSTANCE.getOBS_ComposedAdapterFactory());
			}
			else if(element instanceof Activity) {
				fixTeamProfileDuplicateNames((Activity) element, suppression);
			}
		}
	}
		

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.process.command.BSDropCommand#doUndo()
	 */
	protected void doUndo() {
		activity.getBreakdownElements().removeAll(appliedActivities);
		if (isDeliveryProcess) {
			DeliveryProcess proc = (DeliveryProcess) targetProcess;
			proc.getIncludesPatterns().clear();
			proc.getIncludesPatterns().addAll(oldPatterns);
		}
	}

	public static void setName(List siblings, Activity e) {
		String baseName = e.getName();
		if (!isNameTaken(siblings, e, baseName)) {
			return;
		}
		for (int i = 1; true; i++) {
			String name = baseName + '_' + i;
			if (!isNameTaken(siblings, e, name)) {
				e.setName(name);
				return;
			}
		}
	}

	public static void setDefaultPresentationName(List siblings, Activity e) {
		// if(e.getPresentationName() != null &&
		// e.getPresentationName().trim().length() > 0) return;

		String basePresentationName = ProcessUtil.getPresentationName(e);
		if (!isPresentationNameTaken(siblings, e, basePresentationName)) {
			// e.setPresentationName(basePresentationName);
			return;
		}
		for (int i = 1; true; i++) {
			String name = basePresentationName + '_' + i;
			if (!isPresentationNameTaken(siblings, e, name)) {
				e.setPresentationName(name);
				return;
			}
		}
	}

	private static boolean isNameTaken(List siblings, DescribableElement e,
			String name) {
		for (int i = siblings.size() - 1; i > -1; i--) {
			BreakdownElement sibling = (BreakdownElement) siblings.get(i);
			// if(sibling != e && name.equals(sibling.getPresentationName())) {
			if (sibling != e && name.equals(sibling.getName())) {
				return true;
			}
		}
		return false;
	}

	private static boolean isPresentationNameTaken(List siblings,
			DescribableElement e, String name) {
		for (int i = siblings.size() - 1; i > -1; i--) {
			BreakdownElement sibling = (BreakdownElement) siblings.get(i);
			// if(sibling != e && name.equals(sibling.getPresentationName())) {
			if (sibling != e
					&& name.equals(ProcessUtil.getPresentationName(sibling))) {
				return true;
			}
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.emf.common.command.AbstractCommand#getAffectedObjects()
	 */
	public Collection<?> getAffectedObjects() {
		if(executed) {
			return appliedActivities;
		}
		else {
			return Collections.EMPTY_LIST;
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.emf.common.command.AbstractCommand#getResult()
	 */
	public Collection<?> getResult() {
		return getAffectedObjects();
	}

	public ActivityHandler getActivityHandler() {
		return activityHandler;
	}
	public Activity getActivity(){
		return activity;
	}
	public int getType(){
		return type;
	}

	public void setActivityDeepCopyConfigurator(
			IConfigurator activityDeepCopyConfigurator) {
		this.activityDeepCopyConfigurator = activityDeepCopyConfigurator;
	}
	

}