//------------------------------------------------------------------------------
// 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.ui.util;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.edit.command.RemoveCommand;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.epf.common.ui.util.MsgBox;
import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.library.LibraryResources;
import org.eclipse.epf.library.LibraryServiceUtil;
import org.eclipse.epf.library.edit.LibraryEditResources;
import org.eclipse.epf.library.edit.command.IResourceAwareCommand;
import org.eclipse.epf.library.edit.command.NestedCommandExcecutor;
import org.eclipse.epf.library.edit.util.ExtensionManager;
import org.eclipse.epf.library.edit.util.IOppositeFeatureLoader;
import org.eclipse.epf.library.edit.util.Messenger;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.edit.validation.IValidator;
import org.eclipse.epf.library.edit.validation.IValidatorFactory;
import org.eclipse.epf.library.ui.LibraryUIPlugin;
import org.eclipse.epf.library.util.ContentResourceScanner;
import org.eclipse.epf.library.util.ResourceHelper;
import org.eclipse.epf.persistence.util.PersistenceUtil;
import org.eclipse.epf.services.ILibraryPersister;
import org.eclipse.epf.services.Services;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElementDescription;
import org.eclipse.epf.uma.ContentDescription;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.NamedElement;
import org.eclipse.epf.uma.UmaFactory;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.util.AssociationHelper;
import org.eclipse.epf.uma.util.ContentDescriptionFactory;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;

/**
 * @author Phong Nguyen Le
 * @since  1.0
 */
public class TypeConverter {
	private static final Comparator activityFeatureComparator = new Comparator() {

		public int compare(Object arg0, Object arg1) {
			if(arg0 == UmaPackage.Literals.BREAKDOWN_ELEMENT__SUPER_ACTIVITIES) {
				return -1;
			}
			return 0;
		}
		
	};
	
	/**
	 * Converts the specified object to a object of new type specified by <code>newType</code> while still
	 * preserving as many attributes and relationships as possible
	 * 
	 * @param object
	 * @param newType
	 * @param oldFeatureToNewFeatureMap map of feature of <code>object</code> to feature of <code>newType</code>
	 * @return new object of type <code>newType</code>
	 */
	public static final EObject convert(EObject object, EClass newType,
			Map oldFeatureToNewFeatureMap, Comparator featureComparator, Set modifiedResources) 
	{
		TypeConversionCommand cmd = createTypeConversionCommand(object, newType, oldFeatureToNewFeatureMap, featureComparator);
		Collection<Resource> resources = cmd.getModifiedResources();
		if(!resources.isEmpty()) {
			Resource[] resourceArray = new Resource[resources.size()];
			resources.toArray(resourceArray);
			IStatus status = Services.getAccessController().checkModify(resourceArray, ExtensionManager.getDefaultUserInteractionHandler().getUIContext());
			if(!status.isOK()) {
				Messenger.INSTANCE.showError(LibraryResources.convertActivityError_title, null, status);
				return null;
			}
		}
		try {
			cmd.execute();
			modifiedResources.addAll(cmd.getModifiedResources());
			return (EObject) cmd.getResult().iterator().next();
		}
		finally {
			cmd.dispose();
		}
	}
	
	private static class ResourceCopyTask {
		ContentResourceScanner scanner;
		MethodElement owner;
		String content;
		String contentPath;
		
		/**
		 * @param scanner
		 * @param owner
		 * @param content
		 * @param contentPath
		 */
		public ResourceCopyTask(ContentResourceScanner scanner, MethodElement owner, String content, String contentPath) {
			super();
			this.scanner = scanner;
			this.owner = owner;
			this.content = content;
			this.contentPath = contentPath;
		}	
				
	}
	
	public static class TypeConversionCommand extends CompoundCommand implements IResourceAwareCommand {

		private Collection<?> result;
		private EObject object;
		private HashSet<Resource> modifiedResources;
		private boolean gotModifiedResources;
		private List<ResourceCopyTask> resourceCopyTasks;
		private Resource resource;
		private Collection illegalReferencers;
		private NestedCommandExcecutor nestedCommandExcecutor;

		/**
		 * @param object
		 */
		public TypeConversionCommand(EObject object) {
			this.object = object;
			modifiedResources = new HashSet<Resource>();
			resource = object.eResource();
			if(resource != null) {
				modifiedResources.add(resource);
			}
			resourceCopyTasks = new ArrayList<ResourceCopyTask>();
			nestedCommandExcecutor = new NestedCommandExcecutor(this);
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.emf.common.command.CompoundCommand#dispose()
		 */
		public void dispose() {
			if(illegalReferencers != null) {
				illegalReferencers.clear();
			}
			if(modifiedResources != null) {
				modifiedResources.clear();
			}
			if(resourceCopyTasks != null) {
				resourceCopyTasks.clear();
			}
			if(nestedCommandExcecutor != null) {
				nestedCommandExcecutor.dispose();
			}
			super.dispose();
		}
				
		/**
		 * Gets referencers that become illegal after the type conversion
		 * 
		 * @return
		 */
		public Collection getIllegalReferencers() {
			if(illegalReferencers == null) {
				getModifiedResources();
			}
			return illegalReferencers;
		}
		
		public void copyResources() {
			if(!resourceCopyTasks.isEmpty()) {
				for (ResourceCopyTask t : resourceCopyTasks) {
					File newResourcePath = new File(ResourceHelper.getAbsoluteElementResourcePath(t.owner));
					t.scanner.setTargetRootPath(newResourcePath);
					if(t.content != null) {
						t.scanner.resolveResources(t.owner, t.content, t.contentPath);
					}
					else {
						for (EAttribute attribute : t.owner.eClass().getEAllAttributes()) {
							Object value = t.owner.eGet(attribute);
							if(value instanceof String) {
								t.scanner.resolveResources(t.owner, (String) value, t.contentPath);
							}
						}
					}
				}
			}
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.epf.library.edit.command.IResourceAwareCommand#getModifiedResources()
		 */
		public Collection<Resource> getModifiedResources() {
			if(!gotModifiedResources) {
				illegalReferencers = new HashSet();
				for (Iterator iter = commandList.iterator(); iter.hasNext();) {
					Command cmd = (Command) iter.next();
					if(cmd instanceof RemoveCommand) {
						RemoveCommand removeCommand = (RemoveCommand) cmd;
						EObject owner = removeCommand.getOwner();
						Resource ownerResource = owner.eResource();
						if(ownerResource != null && ownerResource != resource) {
							modifiedResources.add(ownerResource);
						}
						if(ownerResource != null && owner != object && !UmaUtil.isContainedBy(owner, object)) {
							illegalReferencers.add(owner);
						}
					}
					else if(cmd instanceof SetCommand) {
						SetCommand setCommand = (SetCommand) cmd;
						EObject owner = setCommand.getOwner();
						Resource ownerResource = owner.eResource();
						if(ownerResource != null && ownerResource != resource && setCommand.getValue() instanceof EObject) {
							EObject value = (EObject) setCommand.getValue();
							if(value != object || !UmaUtil.isContainedBy(value, object)) {
								modifiedResources.add(ownerResource);
							}
						}
						if(ownerResource != null && owner != object && !UmaUtil.isContainedBy(owner, object)
								&& setCommand.getValue() == setCommand.getFeature().getDefaultValue()) {
							illegalReferencers.add(owner);
						}
					}
				}
				
				gotModifiedResources = true;
			}
			modifiedResources.addAll(nestedCommandExcecutor.getModifiedResources());		
			return modifiedResources;
		}
		
		private void setResult(Collection<?> result) {
			this.result = result;
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.emf.common.command.CompoundCommand#getResult()
		 */
		public Collection<?> getResult() {
			return result;
		}
		
		@Override
		public void execute() {
			super.execute();			
			nestedCommandExcecutor.executeNestedCommands();
		}
		
		@Override
		public void undo() {
			nestedCommandExcecutor.undoNestedCommands();
			super.undo();
		}
		
		private List<Command> commandList() {
			return commandList;
		}
	}
	
	/**
	 * 
	 * @param object EObject
	 * @param newType EClass
	 * @param oldFeatureToNewFeatureMap Map
	 * @param featureComparator Comparator
	 * @return TypeConversionCommand
	 */
	public static final TypeConversionCommand createTypeConversionCommand(EObject object, EClass newType, 
			Map oldFeatureToNewFeatureMap, Comparator featureComparator) {
		return createTypeConversionCommand(object, newType, oldFeatureToNewFeatureMap, featureComparator, false, false);
	}
	
	/**
	 * 
	 * @param object EObject
	 * @param newType EClass
	 * @param oldFeatureToNewFeatureMap Map
	 * @param featureComparator Comparator
	 * @param removeIncomingReferences boolean
	 * @param removeVariability boolean
	 * @return TypeConversionCommand
	 */
	public static final TypeConversionCommand createTypeConversionCommand(EObject object, EClass newType, 
			Map oldFeatureToNewFeatureMap, Comparator featureComparator, 
			boolean removeIncomingReferences, boolean removeVariability) {
		TypeConversionCommand cmd = new TypeConversionCommand(object);
		EObject newObject = prepareConvert(object, newType, oldFeatureToNewFeatureMap, featureComparator, removeIncomingReferences, removeVariability, cmd);
		
		// replace object with newObject in the object's container
		//
		EObject container = object.eContainer();
		if(container != null) {
			EReference ref = object.eContainmentFeature();
			if(ref.isMany()) {
				List list = (List) container.eGet(ref);
				int index = list.indexOf(object);
				cmd.commandList().add(0, new SetCommand(null, container, ref, newObject, index));
			}
			else {
				cmd.commandList().add(0, new SetCommand(null, container, ref, newObject));
			}
		}
		
		cmd.setResult(Collections.singletonList(newObject));
		
		return cmd;
	}
	
	private static ContentResourceScanner createScanner(EObject object) {
		if(object instanceof ContentDescription && !(object instanceof BreakdownElementDescription)) {			
			File oldResourcePath = new File(ResourceHelper.getFolderAbsolutePath((MethodElement) object));
			String rootContentpath = ResourceHelper.getElementPath((MethodElement)object);
			ContentResourceScanner scanner = new ContentResourceScanner(oldResourcePath, null, rootContentpath, null);
			return scanner;
		}
		return null;
	}	
	
	/**
	 * Prepares a compound command to do a type conversion
	 * 
	 * @param object
	 * @param newType
	 * @param oldFeatureToNewFeatureMap
	 * @param featureComparator used to sort the feature list of object to convert before copying/moving
	 *        feature values to new object.
	 * @param removeIncomingReferences if true will remove all incoming references 
	 * @param compoundCommand
	 * @return EObject
	 */
	public static final EObject prepareConvert(EObject object, EClass newType, Map oldFeatureToNewFeatureMap,
			Comparator featureComparator, boolean removeIncomingReferences, boolean removeVariability,
			TypeConversionCommand compoundCommand) {
		EObject newObject = UmaFactory.eINSTANCE.create(newType);
		
		if(object instanceof MethodElement) {
			// Handle incoming references.
			// If removeIncommingReferences is false, redirect all incoming references of object to newObject
			// If removeIncommingReferences is true, remove all of them.
			//			

			MethodElement me = (MethodElement) object;
			Collection oppositeFeatures = me.getOppositeFeatures();
			if(!oppositeFeatures.isEmpty()) {				
				
				// load opposite features
				//
				Collection collection = Collections.singletonList(object);
				for (Iterator iter = ExtensionManager.getOppositeFeatureLoaders().iterator(); iter
						.hasNext();) {
					IOppositeFeatureLoader loader = (IOppositeFeatureLoader) iter.next();
					loader.loadOppositeFeatures(collection);
				}
				
				Map referencerToFeatureListMap = AssociationHelper.getReferenceMap(me);
				for (Iterator iter = referencerToFeatureListMap.entrySet().iterator(); iter
						.hasNext();) {
					Map.Entry entry = (Map.Entry) iter.next();
					EObject referencer = (EObject) entry.getKey();
					for (Iterator iterator = ((Collection)entry.getValue()).iterator(); iterator
							.hasNext();) {
						EReference feature = (EReference) iterator.next();
						if(!removeIncomingReferences && feature.getEType().isInstance(newObject)) {
							// new type is compatible, reference can be preserved
							//
							if(feature.isMany()) {
								List list = (List) referencer.eGet(feature);
								int index = list.indexOf(object);
								compoundCommand.append(new SetCommand(null, referencer, feature, newObject, index));
							}
							else {
								compoundCommand.append(new SetCommand(null, referencer, feature, newObject));
							}
						}
						else {
							// new type is not compatible, reference must be removed
							//
							if(feature.isMany()) {
								compoundCommand.append(new RemoveCommand(null, referencer, feature, object));
							}
							else {
								compoundCommand.append(new SetCommand(null, referencer, feature, feature.getDefaultValue()));
							}
						}
					}
				}
			}
		}
		
		// copy all the features
		//
		List newObjectFeatures = newType.getEAllStructuralFeatures();
		List objectFeatures = new ArrayList(object.eClass().getEAllStructuralFeatures());
		if(removeVariability) {
			objectFeatures.remove(UmaPackage.Literals.VARIABILITY_ELEMENT__VARIABILITY_BASED_ON_ELEMENT);
			objectFeatures.remove(UmaPackage.Literals.VARIABILITY_ELEMENT__VARIABILITY_TYPE);
		}
		if(featureComparator != null) {
			Collections.sort(objectFeatures, featureComparator);
		}
		ContentResourceScanner scanner = createScanner(object);
		for (Iterator iter = objectFeatures.iterator(); iter.hasNext();) {
			EStructuralFeature feature = (EStructuralFeature) iter.next();
			if(!newObjectFeatures.contains(feature)) {
				if(oldFeatureToNewFeatureMap != null) {
					Object f = oldFeatureToNewFeatureMap.get(feature);
					if(f != null && newObjectFeatures.contains(f)) {
						feature = (EStructuralFeature) f;
					}
					else {
						feature = null;
					}
				}
				else {
					feature = null;
				}
			}
			if(feature != null && feature.isChangeable()) {				
				boolean featureHandled = false;
				if(feature instanceof EReference) {
					EReference ref = (EReference) feature;
					if(ref == UmaPackage.Literals.DESCRIBABLE_ELEMENT__PRESENTATION) {
						if(ContentDescriptionFactory.hasPresentation((MethodElement) object)) {
							ContentDescription content = (ContentDescription) object.eGet(ref);
							EClass contentDescType = ContentDescriptionFactory.getContentDescriptionType(newType);
							if(contentDescType != null && contentDescType != content.eClass()) {
								EObject newContent = prepareConvert(content, contentDescType, null, null, removeIncomingReferences, removeVariability, compoundCommand);
								
								// remove old content
								//
								EObject container = content.eContainer();
								if(container != null) {
									compoundCommand.append(new SetCommand(null, object, ref, null));
									Resource resource = content.eResource();
									if(resource != null) {
										compoundCommand.modifiedResources.add(content.eResource());
									}
								}
								
								content = (ContentDescription) newContent;
							}
							else {
								compoundCommand.resourceCopyTasks.add(new ResourceCopyTask(createScanner(content), content, null, "")); //$NON-NLS-1$
							}
							compoundCommand.append(new SetCommand(null, newObject, ref, content));
						}
						featureHandled = true;
					}					
					else if(!ref.isContainment() && ref.getEOpposite() != null) {
						// Reference is bi-directional. If opposite reference is a list, replace object
						// with new object at the same position in the list.
						//
						EReference oppositeRef = ref.getEOpposite();						
						if(oppositeRef.isMany()) {
							Object value = object.eGet(ref);
							if(value != null) {
								if(ref.isMany()) {
									for (Iterator iterator = ((Collection)value)
											.iterator(); iterator.hasNext();) {
										EObject otherEnd = (EObject) iterator.next();
										List list = (List) otherEnd.eGet(oppositeRef);
										int index = list.indexOf(object);
										compoundCommand.append(new SetCommand(null, otherEnd, oppositeRef, newObject, index));
									}
								}
								else {
									EObject otherEnd = (EObject) value;
									List list = (List) otherEnd.eGet(oppositeRef);
									int index = list.indexOf(object);
									compoundCommand.append(new SetCommand(null, otherEnd, oppositeRef, newObject, index));								}
							}
							featureHandled = true;
						}
					}
				}
				if(!featureHandled) {
					Object value = object.eGet(feature);
					if (feature == UmaPackage.Literals.NAMED_ELEMENT__NAME) {
						// validate name
						String newName = checkName(object, newType);
						if (newName != null) {
							value = newName;
						}
					}
					if(scanner != null && value instanceof String && object instanceof MethodElement) {
						String str = (String) value;
						if(!StrUtil.isBlank(str)) {
							compoundCommand.resourceCopyTasks.add(new ResourceCopyTask(scanner, (MethodElement)object, str, "")); //$NON-NLS-1$
						}
					}
					compoundCommand.append(new SetCommand(null, newObject, feature, value));
				}
			}
		}
						
		return newObject;
	}

	/**
	 * Converts an activity to new type.
	 * 
	 * @param oldActivity Activity
	 * @param newType EClass
	 * @return Activity
	 */
	public static Activity convertActivity(Activity oldActivity, EClass newType) {
		// activity is already this type
		//
		if (newType == oldActivity.eClass()) {
			return null;
		}
		
		HashSet<Resource> modifiedResources = new HashSet<Resource>();
		Activity newActivity = (Activity) TypeConverter.convert(oldActivity, newType, null, activityFeatureComparator, modifiedResources);

		// make oldActivity a proxy so reference to it can be resolved to newActivity
		//
		URI uri = PersistenceUtil.getProxyURI(newActivity);
		((InternalEObject)oldActivity).eSetProxyURI(uri);
				
		// save modified resources
		//
		if (!modifiedResources.isEmpty()) {
			ILibraryPersister.FailSafeMethodLibraryPersister persister = LibraryServiceUtil.getCurrentPersister().getFailSafePersister();
			try {
				for (Resource res : modifiedResources) {
					persister.save(res);
				}
				persister.commit();

			} catch (Exception e) {
				LibraryUIPlugin
						.getDefault()
						.getMsgDialog()
						.displayError(
								LibraryResources.convertActivityError_title,
								NLS
										.bind(
												LibraryResources.saveConvertedActivityError_msg,
												newActivity.getName()),
								LibraryResources.error_reason, e);

				persister.rollback();
			}
		}
		
		return newActivity;
	}		
	
	/**
	 * 
	 * @param typeID int
	 * @return EClass
	 */
	public static EClass getActivityType(int typeID) {
		switch (typeID) {
		case UmaPackage.ACTIVITY:
			return UmaPackage.Literals.ACTIVITY;
		case UmaPackage.ITERATION:
			return UmaPackage.Literals.ITERATION;
		case UmaPackage.PHASE:
			return UmaPackage.Literals.PHASE;
		default:
			return null;
		}
	}

	
	/**
	 * @param oldGuidance
	 * @param newGuidance
	 * @return
	 */
	private static String checkName(EObject object, EClass newType) {
		// TODO Auto-generated method stub
		if (object instanceof NamedElement) {
			NamedElement e = (NamedElement)object;
			final IValidator validator = IValidatorFactory.INSTANCE.createNameValidator(e.eContainer(), e, newType);
			String msg = validator.isValid(e.getName());
			if(msg != null) {
				String featureTxt = TngUtil.getFeatureText(UmaPackage.eINSTANCE
						.getNamedElement_Name());
				String title = LibraryEditResources.resolveNameConflictDialog_title; 
				String dlgMsg = NLS.bind(
						LibraryEditResources.resolveNameConflictDialog_text,
						StrUtil.toLower(featureTxt), e.getName());
				String currentValue = (String) e.eGet(UmaPackage.eINSTANCE
						.getNamedElement_Name());
	
				IInputValidator inputValidator = new IInputValidator() {
					public String isValid(String newText) {
						return validator.isValid(newText);
					}
				};
	
				InputDialog inputDlg = new InputDialog(
						MsgBox.getDefaultShell(), title, dlgMsg, currentValue,
						inputValidator);
				if (inputDlg.open() == Window.CANCEL) {
					throw new OperationCanceledException();
				}
				return inputDlg.getValue();
			}
		}
		return null;
	}

}