//------------------------------------------------------------------------------
// 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.Map;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.command.BasicCommandStack;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xml.type.XMLTypePackage.Literals;
import org.eclipse.emf.edit.command.CommandParameter;
import org.eclipse.emf.edit.command.CopyCommand;
import org.eclipse.emf.edit.command.CreateCopyCommand;
import org.eclipse.emf.edit.command.InitializeCopyCommand;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.provider.AdapterFactoryTreeIterator;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.epf.library.edit.IConfigurator;
import org.eclipse.epf.library.edit.IFilter;
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.process.IBSItemProvider;
import org.eclipse.epf.library.edit.util.ConstraintManager;
import org.eclipse.epf.library.edit.util.ExtensionManager;
import org.eclipse.epf.library.edit.util.IDiagramManager;
import org.eclipse.epf.library.edit.util.ITextReferenceReplacer;
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.uma.Activity;
import org.eclipse.epf.uma.Constraint;
import org.eclipse.epf.uma.Diagram;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.ProcessPackage;
import org.eclipse.epf.uma.UmaFactory;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.VariabilityType;
import org.eclipse.epf.uma.edit.command.MethodElementInitializeCopyCommand;
import org.eclipse.osgi.util.NLS;

/**
 * Physically copies an activity with all of its direct or inherited structural features and references.
 *   
 * @author Phong Nguyen Le - Jun 21, 2006
 * @since  1.0
 */
public class ActivityDeepCopyCommand extends CopyCommand {
	private static final AdapterFactory[] adapterFactories = {
		TngAdapterFactory.INSTANCE.getWBS_ComposedAdapterFactory(),
		TngAdapterFactory.INSTANCE.getOBS_ComposedAdapterFactory(),
		TngAdapterFactory.INSTANCE.getPBS_ComposedAdapterFactory()
	};
	
	private static final int[] diagramTypes = {
		IDiagramManager.ACTIVITY_DETAIL_DIAGRAM,
		IDiagramManager.ACTIVITY_DIAGRAM,
		IDiagramManager.WORK_PRODUCT_DEPENDENCY_DIAGRAM
	};
	
	private class EditingDomain extends AdapterFactoryEditingDomain {

		/**
		 * @param adapterFactory
		 * @param commandStack
		 */
		public EditingDomain() {
			super(TngAdapterFactory.INSTANCE.getWBS_ComposedAdapterFactory(), new BasicCommandStack()); 
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain#createCommand(java.lang.Class, org.eclipse.emf.edit.command.CommandParameter)
		 */
		public Command createCommand(Class commandClass, CommandParameter commandParameter) {
			if(commandClass == CreateCopyCommand.class) {
				return new CreateDeepCopyCommand(this, commandParameter.getEOwner(), (Helper) commandParameter.getValue());
			}
			if(commandClass == InitializeCopyCommand.class) {
				return new InitializeDeepCopyCommand(this, commandParameter.getEOwner(), (Helper) commandParameter.getValue());
			}
			return super.createCommand(commandClass, commandParameter);
		}
	}
	
	private static class CreateDeepCopyCommand extends CreateCopyCommand {

		/**
		 * @param domain
		 * @param owner
		 * @param copyHelper
		 */
		public CreateDeepCopyCommand(EditingDomain domain, EObject owner, Helper copyHelper) {
			super(domain, owner, copyHelper);
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.emf.edit.command.CreateCopyCommand#doGetChildrenToCopy()
		 */
		public Collection doGetChildrenToCopy() {
			// Create commands to create copies of the children.
			//
			List result = new ArrayList();
			for (Iterator i = owner.eContents().iterator(); i.hasNext(); )
			{
				Object o = i.next();
				if(o instanceof Activity) {
					// make sure that Activity will be copied first
					// so references to its inherited elements can be resolved properly
					//
					result.add(0, o);
				}
				else {
					result.add(o);
				}
			}
			return result;

		}
		
	}
	
	private class InitializeDeepCopyCommand extends MethodElementInitializeCopyCommand {

		/**
		 * @param domain
		 * @param owner
		 * @param copyHelper
		 */
		public InitializeDeepCopyCommand(EditingDomain domain, EObject owner, Helper copyHelper) {
			super(domain, owner, copyHelper);
			copy = (EObject) copyHelper.get(owner);
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.epf.uma.edit.command.MethodElementInitializeCopyCommand#copyReferences()
		 */
		protected void copyReferences() {
			Activity base = null;
			Activity baseCopy = null;
			Collection childBaseCopies = new HashSet();
			if(owner instanceof Activity) {
				Activity activity = (Activity) owner;
				if(ProcessUtil.isExtendingOrLocallyContributing(activity)) {
					// copy inherited elements by deep-copying base activity
					//
					// deep copy of base activity at this point is essential so references to predecessors
					// will be copied correctly
					//
					base = (Activity) activity.getVariabilityBasedOnElement();
					CopyHelper helper = (CopyHelper)copyHelper;
					Activity oldBaseCopy = (Activity) helper.get(base);
					// this will redirect any reference to copy of base in diagram to the copy of the activity
					//
					helper.putVariabilityElement(base, activity);
					ArrayList childBases = new ArrayList();
					for (Iterator iter = activity.getBreakdownElements().iterator(); iter.hasNext();) {
						Object e = iter.next();
						if(e instanceof VariabilityElement) {
							VariabilityElement ve = (VariabilityElement) e;
							VariabilityElement baseElement = ve.getVariabilityBasedOnElement();
							if(baseElement != null &&
									(ve.getVariabilityType() == VariabilityType.LOCAL_CONTRIBUTION_LITERAL || ve.getVariabilityType() == VariabilityType.LOCAL_REPLACEMENT_LITERAL))
							{
								helper.putVariabilityElement(baseElement, ve);
								childBases.add(baseElement);
							}
						}
					}
					
					ActivityDeepCopyCommand cmd = new ActivityDeepCopyCommand(base, helper, config, targetProcess, monitor);
					try {
						cmd.execute();
						
						baseCopy = (Activity) helper.get(base);
						if(activity.getVariabilityType() == VariabilityType.EXTENDS_LITERAL) {
							// keep activity only as backup copy of base
							//
							helper.removeVariabilityElement(base);
							helper.putBackupCopy(base, activity);
							
							// put back oldBaseCopy
							if(oldBaseCopy != null) {
								helper.basicPut(base, oldBaseCopy);
							}
						}
						
						// remove the copies of all base since base copies are not added to the process
						//
						helper.remove(base);
						for (Iterator iter = childBases.iterator(); iter.hasNext();) {
							EObject childBaseCopy = (EObject) helper.remove(iter.next());
							childBaseCopies.add(childBaseCopy);
							EcoreUtil.remove(childBaseCopy.eContainer());
						}
						
						Activity activityCopy = (Activity) copy;
						
						// remove the copies of base diagram if the activity already have diagram of the same type
						//
						for (int i = 0; i < diagramTypes.length; i++) {
							int type = diagramTypes[i];
							if(diagramMgr.getDiagram(activity, type) != null) {
								Diagram diagram = diagramMgr.getDiagram(activityCopy, type);
								if(diagram != null) {
									EcoreUtil.remove(diagram);
								}
							}
						}
						
						// move content of base package over to the activity's package
						//
						moveContent(cmd.pkgCopy, activityCopy);							
					}
					finally {
						cmd.dispose();
					}
				}
			}
			
			super.copyReferences();
			
			if(base != null) {
				// copy inherited breakdown elements from the base activity in the right order
				//
				IConfigurator configurator = null;
				MethodConfiguration currentConfig = null;
				IFilter filter = ProcessUtil.getFilter(((AdapterFactoryEditingDomain)domain).getAdapterFactory());
				if(filter instanceof IConfigurator) {
					configurator = (IConfigurator) filter;
					currentConfig = configurator.getMethodConfiguration();
					configurator.setMethodConfiguration(config);
				}
				try {
					Activity activity = (Activity) owner;
					Activity activityCopy = ((Activity) copy);					
					
					// Add breakdown elements from base copy to the activity copy. 
					// Don't add copy of base element of the existing children
					//
					List breakdownElements = new ArrayList();
					for (Iterator iter = baseCopy.getBreakdownElements().iterator(); iter.hasNext();) {
						Object e = iter.next();
						if(!childBaseCopies.contains(e)) {
							breakdownElements.add(e);
						}						
					}
					activityCopy.getBreakdownElements().addAll(0, breakdownElements);
					EcoreUtil.remove(baseCopy);
					
					// copy other string attributes as well after realize them
					//
					for (Iterator iter = getAttributesToCopy().iterator(); iter.hasNext();) {
						EAttribute attribute = (EAttribute) iter.next();
						Object value = Providers.getConfigurationApplicator().getAttribute(activity, attribute, config);
						activityCopy.eSet(attribute, value);
					}
					
					// copy presentation name
					//
					activityCopy.setPresentationName(ProcessUtil.getPresentationName(activity));					

					// clear the variability data
					//
					activityCopy.setVariabilityBasedOnElement(null);
					activityCopy.setVariabilityType(null);

					// clear suppression data
					//
					Constraint rule = ConstraintManager.getConstraint(activityCopy, ConstraintManager.PROCESS_SUPPRESSION, false);
					if(rule != null) {
						EcoreUtil.remove(rule);
					}
				}
				finally {
					if(configurator != null) {
						// restore current configruation
						//
						configurator.setMethodConfiguration(currentConfig);
					}
				}
			}
		}		
	}

	protected ProcessPackage pkgCopy;
	protected MethodConfiguration config;
	protected IDiagramManager diagramMgr;

	protected Process targetProcess;

	protected IProgressMonitor monitor;

	protected Activity activity;

	public ActivityDeepCopyCommand(Activity activity, CopyHelper copyHelper, MethodConfiguration config, Process targetProcess, IProgressMonitor monitor) {
		super(null, activity.eContainer(), copyHelper);
		Assert.isTrue(activity.eContainer() instanceof ProcessPackage, "Activity's container must be a ProcessPackage"); //$NON-NLS-1$
		domain = new EditingDomain();
		this.config = config;
		this.targetProcess = targetProcess;
		diagramMgr = ExtensionManager.getDiagramManager();
		Assert.isNotNull(diagramMgr, "Could not load diagram manager"); //$NON-NLS-1$
		this.monitor = monitor;
		this.activity = activity;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.emf.edit.command.CopyCommand#execute()
	 */
	public void execute() {
		monitor.subTask(NLS.bind(LibraryEditResources.copyingActivities_msg, ProcessUtil.getPresentationName(activity)));
		super.execute();
		Collection result = super.getResult();
		if(!result.isEmpty()) {
			pkgCopy = (ProcessPackage) result.iterator().next();
			fixProcessComponent();
			replaceTextReferences();
		}
	}
	
	/**
	 * fix the process component to make it a process package.
	 * This method might be overriden by subclass to achive difference result.
	 * For example, 
	 * @see org.eclipse.emf.edit.command.ProcessDeepCopyCommand#fixProcessComponent()
	 *
	 */
	protected void fixProcessComponent() {
		if(pkgCopy instanceof ProcessComponent) {
			// replace the ProcessComponent with a equivalent ProcessPackage
			//
			ProcessPackage pkg = UmaFactory.eINSTANCE.createProcessPackage();
			Collection features = new ArrayList(pkgCopy.eClass().getEAllStructuralFeatures());
			features.retainAll(pkg.eClass().getEAllStructuralFeatures());
			for (Iterator iter = features.iterator(); iter.hasNext();) {
				EStructuralFeature feature = (EStructuralFeature) iter.next();
				Object value = pkgCopy.eGet(feature);
				pkg.eSet(feature, value);
			}
			Process proc = ((ProcessComponent)pkgCopy).getProcess();
			if(proc != null) {
				pkg.getProcessElements().add(0, proc);
			}
			pkgCopy = pkg;
		}		
	}
	
	/**
	 * If textual descriptions in the copied elements contain references (URLs) to other elements 
	 * within the same copied process then replace these references with references that point to 
	 * the new elements in the copied structures.
	 */
	protected void replaceTextReferences() {
		ITextReferenceReplacer txtRefReplacer = ExtensionManager.getTextReferenceReplacer();
		if(txtRefReplacer == null) return;

		Map oldToNewObjectMap = ((CopyHelper) copyHelper).getObjectToCopyMap();
		for (Iterator iter = pkgCopy.eAllContents(); iter.hasNext();) {
			EObject element = (EObject) iter.next();
			for (Iterator attributes = element.eClass().getEAllAttributes().iterator(); attributes.hasNext(); )
			{
				EAttribute attribute = (EAttribute) attributes.next();
				if (attribute.isChangeable() && !attribute.isDerived() && (attribute.isMany() || element.eIsSet(attribute))
						&& attribute.getEAttributeType().getInstanceClass() == Literals.STRING.getInstanceClass())
				{
					String text = (String) element.eGet(attribute);
					if(text != null) {
						text = txtRefReplacer.replace(text, targetProcess, oldToNewObjectMap);
						element.eSet(attribute, text);
					}
				}
			}
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.emf.common.command.CompoundCommand#getResult()
	 */
	public Collection getResult() {
		if(pkgCopy != null) {
			Activity act = ProcessUtil.findActivity(pkgCopy);
			if(act != null) {
				return Collections.singletonList(act);
			}
		}
		return Collections.EMPTY_LIST;
	}
	
	/**
	 * Moves content of source object <code>src</code> over to the target objec <code>target</code>
	 * @param src
	 * @param target
	 */
	private static void moveContent(ProcessPackage src, Activity act) {
		ProcessPackage target = (ProcessPackage) act.eContainer();
		// move content of base package over to the activity's package					
		for (Iterator iter = new ArrayList(src.eContents()).iterator(); iter.hasNext();) {
			EObject e = (EObject) iter.next();
			EStructuralFeature f = e.eContainingFeature();						
			if(f.isMany()) {
				((List)target.eGet(f)).add(e);
			}
		}
		if(src instanceof ProcessComponent) {
			Process baseCopy = ((ProcessComponent)src).getProcess();
			target.getProcessElements().add(baseCopy);
		}

	}
	
	public void copySuppressionStates() {
		for (int i = 0; i < adapterFactories.length; i++) {
			AdapterFactory adapterFactory = adapterFactories[i];
			Activity act = ProcessUtil.findActivity((ProcessPackage) owner);
			ITreeItemContentProvider ip = (ITreeItemContentProvider) adapterFactory.adapt(act, ITreeItemContentProvider.class);
			IBSItemProvider bsIp = (IBSItemProvider) ip;
			Object top = bsIp.getTopItem();
			if(!(top instanceof Process) || !(((EObject)top).eContainer() instanceof ProcessComponent)) {
				// item provider tree of the owner's process is not initialized yet
				//
				ProcessUtil.initializeItemProviderPath(act, adapterFactory);
			}
			Process proc = TngUtil.getOwningProcess(act);
			Suppression suppression = Suppression.getSuppression(proc);
			Iterator iter = new AdapterFactoryTreeIterator(adapterFactory, proc);
//			for (Iterator iter = ip.getChildren(owner).iterator(); iter.hasNext();) {
			while(iter.hasNext()) {
				Object child = iter.next();
				Object e = TngUtil.unwrap(child);
				MethodElement copy = (MethodElement) copyHelper.get(e);

				// copy suppression state, consider current process that inherits this element
				//
				if(copy != null && suppression.isSuppressed(child)) {
					copy.setSuppressed(Boolean.TRUE);
				}
			}
		}
	}
}