package org.eclipse.epf.library.util;

import java.util.ArrayList;
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.emf.ecore.EClass;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.epf.common.utils.FileUtil;
import org.eclipse.epf.library.LibraryPlugin;
import org.eclipse.epf.library.LibraryServiceUtil;
import org.eclipse.epf.library.configuration.ConfigurationHelper;
import org.eclipse.epf.library.configuration.DefaultElementRealizer;
import org.eclipse.epf.library.configuration.ElementRealizer;
import org.eclipse.epf.library.edit.util.DescriptorPropUtil;
import org.eclipse.epf.library.edit.util.LibraryEditUtil;
import org.eclipse.epf.library.edit.util.MethodLibraryPropUtil;
import org.eclipse.epf.library.edit.util.MethodPluginPropUtil;
import org.eclipse.epf.library.edit.util.ProcessPropUtil;
import org.eclipse.epf.library.edit.util.ProcessScopeUtil;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.persistence.MultiFileXMIResourceImpl;
import org.eclipse.epf.services.ILibraryPersister;
import org.eclipse.epf.uma.ContentDescription;
import org.eclipse.epf.uma.ContentElement;
import org.eclipse.epf.uma.Deliverable;
import org.eclipse.epf.uma.Descriptor;
import org.eclipse.epf.uma.DescriptorDescription;
import org.eclipse.epf.uma.Guidance;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.Role;
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.WorkProduct;
import org.eclipse.epf.uma.WorkProductDescriptor;

public class SynFreeProcessConverter {

	private boolean debug = false;

	private ElementRealizer realizer;

	private MethodConfiguration config;

	private ElementRealizer getRealizer() {
		return realizer;
	}

	private void setRealizer(ElementRealizer realizer) {
		this.realizer = realizer;
	}

	private Set<Resource> resouresToSave;

	private UmaPackage up = UmaPackage.eINSTANCE;

	public SynFreeProcessConverter() {
	}

	public SynFreeProcessConverter(MethodConfiguration config) {
		this.config = config;
	}

	private MethodConfiguration getConfig(Process proc) {
		return config == null ? proc.getDefaultContext() : config;
	}

	public void convertLibrary(MethodLibrary lib) throws Exception {
		convertLibrary(lib, true);
	}

	public void convertLibrary(MethodLibrary lib, boolean toSave) throws Exception {
		if (debug) {
			System.out.println("LD> Begin convertLibrary: " + lib); //$NON-NLS-1$
			System.out.println(""); //$NON-NLS-1$
		}
		convertLibrary_(lib, toSave);
		if (debug) {
			System.out.println("LD> End convertLibrary: " + lib); //$NON-NLS-1$
			System.out.println(""); //$NON-NLS-1$
		}
	}

	private void convertLibrary_(MethodLibrary lib, boolean toSave) throws Exception {
		if (lib == null) {
			return;
		}
		List<MethodPlugin> plugins = lib.getMethodPlugins();

		if (toSave) {
			resouresToSave = new HashSet<Resource>();
		}
		for (int i = 0; i < plugins.size(); i++) {
			convertPlugin(plugins.get(i), false);
		}

		MethodLibraryPropUtil propUtil = MethodLibraryPropUtil
				.getMethodLibraryPropUtil();
		propUtil.setSynFree(lib, true);
		if (toSave) {
			resouresToSave.add(lib.eResource());
			save();
		}
	}

	public void convertPlugin(MethodPlugin plugin, boolean toSave) throws Exception {
		if (plugin == null) {
			return;
		}
		if (debug) {
			System.out.println("LD> convertPlugin: " + plugin); //$NON-NLS-1$
			System.out.println(""); //$NON-NLS-1$
		}
		if (toSave) {
			resouresToSave = new HashSet<Resource>();
		}
		Set<Process> processes = LibraryEditUtil.getInstance()
				.collectProcesses(plugin);
		for (Process proc : processes) {
			convertProcess(proc, false);
		}

		MethodPluginPropUtil propUtil = MethodPluginPropUtil
				.getMethodPluginPropUtil();
		propUtil.setSynFree(plugin, true);
		if (resouresToSave != null) {
			Resource res = plugin.eResource();
			if (res != null) {
				resouresToSave.add(res);
			}
		}
		if (toSave) {
			save();
		}
	}

	public void convertProcess(Process proc, boolean toSave) throws Exception {
		if (proc == null) {
			return;
		}
		if (proc.getDefaultContext() == null) {
			ProcessScopeUtil.getInstance().loadScope(proc);
		}
		if (proc.getDefaultContext() == null) {
			return;
		}
		if (debug) {
			System.out.println("LD> convertProcess: " + proc); //$NON-NLS-1$
			System.out.println(""); //$NON-NLS-1$
		}

		MethodConfiguration c = getConfig(proc);
		ElementRealizer r = DefaultElementRealizer.newElementRealizer(c);
		setRealizer(r);

		Set<Descriptor> descriptors = LibraryEditUtil.getInstance()
				.collectDescriptors(proc);

		if (toSave) {
			resouresToSave = new HashSet<Resource>();
		}
		for (Descriptor des : descriptors) {
			convert(proc, des);
		}
		ProcessPropUtil.getProcessPropUtil().setSynFree(proc, true);
		if (resouresToSave != null) {
			Resource res = proc.eResource();
			if (res != null) {
				resouresToSave.add(res);
			}
		}
		if (toSave) {
			save();
		}
	}

	private void convert(Process proc, Descriptor des) {
		boolean oldDeliver = des.eDeliver();
		try {
			if (oldDeliver) {
				des.eSetDeliver(false);
			}
			convert_(proc, des);
		} finally {
			if (oldDeliver) {
				des.eSetDeliver(oldDeliver);
			}
		}
	}

	private void convert_(Process proc, Descriptor des) {
		Resource res = des.eResource();
		if (res == null) {
			return;
		}
		if (debug) {
			System.out.println("LD> convert: " + des); //$NON-NLS-1$
		}

		if (des instanceof TaskDescriptor) {
			convertTd(proc, (TaskDescriptor) des);

		} else if (des instanceof RoleDescriptor) {
			convertRd(proc, (RoleDescriptor) des);

		} else if (des instanceof WorkProductDescriptor) {
			convertWpd(proc, (WorkProductDescriptor) des);

		}

		convertGuidances(proc, des);
		
		convertTextAttributes(proc, des);

		if (resouresToSave != null) {
			resouresToSave.add(res);
		}
	}

	public static boolean equalsIgnoreSuffixNumber(String eString, String dString) {
		if (eString == null) {
			return dString == null;
		}
		if (dString == null) {
			return false;
		}
		if (dString.equals(eString)) {
			return true;
		}
		
		if (dString.startsWith(eString + "_")) { //$NON-NLS-1$
			int ix = eString.length() + 1;
			String str = dString.substring(ix);
			try {
				int n = Integer.parseInt(str);
				return n >= 0;
			} catch (Exception e) {
				return false;
			}
		}
		
		return false;
	}
	
	private void convertTextAttributes(Process proc, Descriptor des) {
		DescriptorPropUtil propUtil = DescriptorPropUtil.getDesciptorPropUtil();
		ContentElement element = (ContentElement) propUtil.getLinkedElement(des);
		if (element == null) {
			return;
		}

		if (propUtil.hasNoValue(des.getName())) {
			des.setName(element.getName());
//		} else if (!des.getName().equals(element.getName())) {
		} else if (! equalsIgnoreSuffixNumber(element.getName(), des.getName())) {			
			propUtil.setNameRepalce(des, true);
		}

		String elementStrValue = ConfigurationHelper.getPresentationName(element, getConfig(proc));
		if (propUtil.hasNoValue(des.getPresentationName())) {
			des.setPresentationName(element.getPresentationName());
//		} else if (!des.getPresentationName().equals(
//				element.getPresentationName())) {
		} else if (! equalsIgnoreSuffixNumber(element.getPresentationName(), des.getPresentationName())) {	
			propUtil.setPresentationNameRepalce(des, true);
		}

		elementStrValue = (String) ConfigurationHelper
				.calcAttributeFeatureValue(element, up
						.getMethodElement_BriefDescription(), getConfig(proc));
		if (propUtil.hasNoValue(des.getBriefDescription())) {
			des.setBriefDescription(elementStrValue);
		} else if (!des.getBriefDescription().equals(
				elementStrValue)) {
			propUtil.setBriefDesRepalce(des, true);
		}
		
		ContentDescription ePrentation = element.getPresentation();
		DescriptorDescription dPrentation = (DescriptorDescription) des
				.getPresentation();
		
		boolean oldDeliver = dPrentation.eDeliver();
		try {
			if (oldDeliver) {
				dPrentation.eSetDeliver(false);
			}

			elementStrValue = (String) ConfigurationHelper
					.calcAttributeFeatureValue(ePrentation, element, up
							.getContentDescription_MainDescription(),
							getConfig(proc));
			if (propUtil.hasNoValue(dPrentation.getRefinedDescription())) {
				dPrentation.setRefinedDescription(elementStrValue);
			} else if (!dPrentation.getRefinedDescription().equals(
					elementStrValue)) {
				propUtil.setMainDesRepalce(des, true);
			}

			elementStrValue = (String) ConfigurationHelper
					.calcAttributeFeatureValue(ePrentation, element, up
							.getContentDescription_KeyConsiderations(),
							getConfig(proc));
			if (propUtil.hasNoValue(dPrentation.getKeyConsiderations())) {
				dPrentation.setKeyConsiderations(elementStrValue);
			} else if (!dPrentation.getKeyConsiderations().equals(
					elementStrValue)) {
				propUtil.setKeyConsiderRepalce(des, true);
			}

		} finally {
			if (oldDeliver) {
				dPrentation.eSetDeliver(oldDeliver);
			}
		}

	}

	private void convertTd(Process proc, TaskDescriptor td) {
		Task task = (Task) getLinkedElement(td);
		if (task == null) {
			return;
		}

		convertManyEReference(proc, td, task, up
				.getTaskDescriptor_PerformedPrimarilyBy(), up
				.getTaskDescriptor_PerformedPrimarilyByExcluded(), up
				.getTask_PerformedBy());

		convertManyEReference(proc, td, task, up
				.getTaskDescriptor_AdditionallyPerformedBy(), up
				.getTaskDescriptor_AdditionallyPerformedByExclude(), up
				.getTask_AdditionallyPerformedBy());

		convertManyEReference(proc, td, task, up.getTaskDescriptor_MandatoryInput(),
				up.getTaskDescriptor_MandatoryInputExclude(), up
						.getTask_MandatoryInput());

		convertManyEReference(proc, td, task, up.getTaskDescriptor_OptionalInput(),
				up.getTaskDescriptor_OptionalInputExclude(), up
						.getTask_OptionalInput());

		convertManyEReference(proc, td, task, up.getTaskDescriptor_Output(), up
				.getTaskDescriptor_OutputExclude(), up.getTask_Output());

		convertManyEReference(proc, td, task, up.getTaskDescriptor_SelectedSteps(),
				up.getTaskDescriptor_SelectedStepsExclude(), up.getTask_Steps());

	}

	private void convertManyEReference(Process proc, Descriptor ownerDescriptor,
			MethodElement ownerLinkedElement, EReference dFeature,
			EReference dFeatureExclude, EReference efeature) {
		DescriptorPropUtil propUtil = DescriptorPropUtil.getDesciptorPropUtil();

		List<MethodElement> elements = ConfigurationHelper.calc0nFeatureValue(
				ownerLinkedElement, efeature, getRealizer());

		List<MethodElement> descriptors = ConfigurationHelper
				.calc0nFeatureValue(ownerDescriptor, dFeature, getRealizer());

		// exclude list and local list
		List<MethodElement> excludeList = (List<MethodElement>) ownerDescriptor
				.eGet(dFeatureExclude);
		List<Descriptor> localList = new ArrayList<Descriptor>();
		Set<MethodElement> elementSet = new HashSet<MethodElement>();

		if (elements != null && !elements.isEmpty()) {
			elementSet.addAll(elements);
		}

		List<MethodElement> linkedElements = new ArrayList<MethodElement>();
		Set<MethodElement> linkedElementSet = new HashSet<MethodElement>();

		if (descriptors != null) {
			for (MethodElement des : descriptors) {
				if (des instanceof Descriptor) {
					Descriptor d = (Descriptor) des;
					MethodElement linkedElement = getLinkedElement(d);
					if (linkedElement == null) {
						localList.add(d);
					} else {
						linkedElementSet.add(linkedElement);
						if (elementSet.contains(linkedElement)) {
							propUtil.setCreatedByReference(d, true);
						} else {
							localList.add(d);
						}
					}
				} else {
					linkedElementSet.addAll(descriptors);
					break;
				}
			}
		}

		for (MethodElement element : elements) {
			if (!linkedElementSet.contains(element)) {
				excludeList.add(element);
			}
		}

		// Handle localList
		for (Descriptor des : localList) {
			propUtil.addLocalUse(des, ownerDescriptor, dFeature);
		}
	}

	private void convertGuidances(Process proc, Descriptor des) {
		MethodElement element = ProcessUtil.getAssociatedElement(des);
		if (element == null) {
			return;
		}

		Map<EReference, EReference> refMap = LibraryEditUtil.getInstance()
				.getGuidanceRefMap(getLinkedElementType(des));
		if (refMap == null) {
			return;
		}

		Set<Guidance> elementGuidanceSet = new HashSet<Guidance>();
		Set<Guidance> descripGuidanceSet = new HashSet<Guidance>();
		for (Map.Entry<EReference, EReference> entry : refMap.entrySet()) {
			EReference elementRef = entry.getKey();
			EReference descripRef = entry.getValue();
			Object elementValue = ConfigurationHelper.calc0nFeatureValue(
					element, elementRef, getRealizer());
			Object descripValue = ConfigurationHelper.calc0nFeatureValue(
					des, descripRef, getRealizer());
			if (elementValue instanceof List) {
				List list = (List) elementValue;
				if (!list.isEmpty()) {
					elementGuidanceSet.addAll((List) elementValue);
				}
				
				Object rawDescripValue = des.eGet(descripRef);
				if (rawDescripValue instanceof List) {
					List rawList = (List) rawDescripValue;
					Set<Guidance> rewDescripGuidanceSet = new HashSet<Guidance>(rawList);
					for (Guidance g : (List<Guidance>) list) {
						if (! rewDescripGuidanceSet.contains(g)) {
							rawList.add(g);
						}
					}
				}
			}
			if (descripValue instanceof List) {
				List list = (List) descripValue;
				if (!list.isEmpty()) {
					descripGuidanceSet.addAll((List) descripValue);
				}
			}
			
		}
//		for (Guidance g : elementGuidanceSet) {
//			if (!descripGuidanceSet.contains(g)) {
//				des.getGuidanceExclude().add(g);
//			}
//		}
		for (Guidance g : descripGuidanceSet) {
			if (!elementGuidanceSet.contains(g)) {
				des.getGuidanceAdditional().add(g);
			}
		}
	}	
	
	private void convertRd(Process proc, RoleDescriptor rd) {
		Role role = (Role) getLinkedElement(rd);
		if (role == null) {
			return;
		}

		convertManyEReference(proc, rd, role, up.getRoleDescriptor_ResponsibleFor(),
				up.getRoleDescriptor_ResponsibleForExclude(), up
						.getRole_ResponsibleFor());
	}

	private void convertWpd(Process proc, WorkProductDescriptor wpd) {
		WorkProduct wp = (WorkProduct) getLinkedElement(wpd);
		if (wp == null) {
			return;
		}

		if (wp instanceof Deliverable) {
			convertManyEReference(proc, wpd, wp, up
					.getWorkProductDescriptor_DeliverableParts(), up
					.getWorkProductDescriptor_DeliverablePartsExclude(), up
					.getDeliverable_DeliveredWorkProducts());
		}
	}

	private void save() throws Exception {
		ILibraryPersister.FailSafeMethodLibraryPersister persister = LibraryServiceUtil
				.getCurrentPersister().getFailSafePersister();

		try {
			List<String> modifiedFiles = new ArrayList<String>();
			for (Resource res : resouresToSave) {
				String path = res.getURI().toFileString();
				modifiedFiles.add(path);
			}
			IStatus status = FileUtil.syncExecCheckModify(modifiedFiles);
			// To do: check status and handle bad status here.
			// For now, leave the following catch to handle bad status
			
			for (Iterator<Resource> it = resouresToSave.iterator(); it
					.hasNext();) {
				MultiFileXMIResourceImpl res = (MultiFileXMIResourceImpl) it
						.next();
				res.setModified(true);
				persister.save(res);
			}
			persister.commit();

		} catch (Exception e) {
			persister.rollback();
			LibraryPlugin.getDefault().getLogger().logError(e);
			String msg = "Cannot save file during converions. Likely caused by some file being read-only."; //$NON-NLS-1$
			LibraryPlugin.getDefault().getLogger().logInfo(msg);
			throw e;			
		} finally {
		}
	}

	private MethodElement getLinkedElement(Descriptor des) {
		MethodElement element = DescriptorPropUtil.getDesciptorPropUtil()
				.getLinkedElement(des);
		if (element == null) {
			return null;
		}
		return ConfigurationHelper.getCalculatedElement(element, getRealizer());
	}

	public static EClass getLinkedElementType(Descriptor des) {
		if (des instanceof TaskDescriptor) {
			return UmaPackage.eINSTANCE.getTask();
		}
		if (des instanceof RoleDescriptor) {
			return UmaPackage.eINSTANCE.getRole();
		}
		if (des instanceof WorkProductDescriptor) {
			return UmaPackage.eINSTANCE.getWorkProduct();
		}
	
		throw new UnsupportedOperationException();
	}
}
