//------------------------------------------------------------------------------
// 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.command.IUserInteractionHandler;
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.ExtensionManager;
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;
	}
	

}