package org.eclipse.epf.library.realization.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.emf.ecore.EReference;
import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.configuration.ConfigurationHelper;
import org.eclipse.epf.library.edit.meta.TypeDefUtil;
import org.eclipse.epf.library.edit.process.command.CustomizeDescriptorCommand;
import org.eclipse.epf.library.edit.process.command.ProcessCommandUtil;
import org.eclipse.epf.library.edit.realization.IRealizationManager;
import org.eclipse.epf.library.edit.realization.IRealizedDescriptor;
import org.eclipse.epf.library.edit.realization.IRealizedElement;
import org.eclipse.epf.library.edit.util.DescriptorPropUtil;
import org.eclipse.epf.library.edit.util.LibraryEditUtil;
import org.eclipse.epf.library.edit.util.ProcessScopeUtil;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.Descriptor;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessPackage;
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.UmaFactory;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.WorkProduct;
import org.eclipse.epf.uma.WorkProductDescriptor;
import org.eclipse.epf.uma.util.Scope;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveListener;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;

public class RealizationManager implements IRealizationManager {

	private Map<MethodElement, IRealizedElement> elementMap;
	private MethodConfiguration config;
	private MethodConfiguration dynamicConfig;

	private boolean caching = false;
	private IPerspectiveListener perspectiveListener;
	private boolean localTiming = true;	
	
	public boolean isCaching() {
		return caching;
	}

	public void setCaching(boolean caching) {
		this.caching = caching;
	}

	private Map<MethodElement, IRealizedElement> getElementMap() {
		if (elementMap == null) {
			elementMap = new HashMap<MethodElement, IRealizedElement>();
		}
		return elementMap;
	}
	
	public RealizationManager(MethodConfiguration config) {
		this.config = config;
		init();
	}
	
	public void clearCacheData() {
		for (IRealizedElement element : getElementMap().values()) {
			((RealizedElement) element).dispose();
		}		
		elementMap = null;
	}
	
	public void dispose() {
		clearCacheData();
		
		IWorkbenchWindow window = LibraryUtil.getActiveWorkbenchWindow();
		if (window != null && perspectiveListener != null) {
			window.removePerspectiveListener(perspectiveListener);
		}
	}
	
	public MethodConfiguration getConfig() {
		if (config == null) {	//Default RealizationManager instance would not have a null config
			return dynamicConfig;
		}
		return config;
	}	

	public IRealizedElement getRealizedElement(MethodElement element) {
		IRealizedElement rElement = getElementMap().get(element);
		if (rElement == null) {
			rElement = newRealizedElement(element);
			getElementMap().put(element, rElement);
		}
		return rElement;
	}
	
	public IRealizedElement removeRealizedElement(MethodElement element) {
		return getElementMap().remove(element);
	}
	
	private void init() {
		IWorkbenchWindow window = LibraryUtil.getActiveWorkbenchWindow();
		if (window != null) {
			perspectiveListener = new IPerspectiveListener() {
				public void perspectiveActivated(IWorkbenchPage page,
						IPerspectiveDescriptor desc) {
					clearCacheData();
				}

				public void perspectiveChanged(IWorkbenchPage page,
						IPerspectiveDescriptor desc, String id) {
					clearCacheData();
				}
			};
			window.addPerspectiveListener(perspectiveListener);
		}
	}
	
	private IRealizedElement newRealizedElement(MethodElement element) {
		RealizedElement rElement = null;
		if (element instanceof TaskDescriptor) {
			rElement = new RealizedTaskDescriptor((TaskDescriptor) element);
			
		} else if (element instanceof RoleDescriptor) {
			rElement = new RealizedRoleDescriptor((RoleDescriptor) element);
			
		} else if (element instanceof WorkProductDescriptor) {
			rElement = new RealizedWorkProductDescriptor((WorkProductDescriptor) element);
			
		} else if (element instanceof BreakdownElement) {
			rElement = new RealizedBreakdownElement((BreakdownElement) element);
			
		}
					
		rElement.setMgr(this);
		
		return rElement;
	}
	
	private MethodElement getLinkedElement(MethodElement element) {
		if (element instanceof RoleDescriptor) {
			return ((RoleDescriptor) element).getRole();
		}
		
		if (element instanceof WorkProductDescriptor) {
			return ((WorkProductDescriptor) element).getWorkProduct();
		}
		
		if (element instanceof TaskDescriptor) {
			return ((TaskDescriptor) element).getTask();
		}
		
		return null;
	}

	public Descriptor getDescriptor(Descriptor referencingDes, Activity parentAct, MethodElement element, EReference feature) {
		Descriptor descriptor = getDescriptor_(referencingDes, parentAct, element, feature);
		if (feature == IRealizedDescriptor.ArtifactDescriptor_ContainedArtifacts) {
			return descriptor;
		}		
		
		boolean oldDeliver = referencingDes.eDeliver();
		referencingDes.eSetDeliver(false);
		LibraryEditUtil libEditUtil = LibraryEditUtil.getInstance();
		try {
			if (feature.isMany()) {
//				List listValue = (List) referencingDes.eGet(feature);
				List listValue = (List) TypeDefUtil.getInstance().eGet(referencingDes, feature, true);
				if (listValue != null) {
					listValue.add(descriptor);
					libEditUtil.addOppositeFeature(referencingDes, descriptor, feature);
				}
			} else {
				referencingDes.eSet(feature, descriptor);
				libEditUtil.addOppositeFeature(referencingDes, descriptor, feature);
			}
		} finally {
			referencingDes.eSetDeliver(oldDeliver);
		}

		return descriptor;
	}
	
	private Descriptor getDescriptor_(Descriptor referencingDes, Activity parentAct, MethodElement element, EReference feature) {
		if (parentAct == null) {
			return null;
		}
		
		Object foundDes = ProcessCommandUtil.getBestDescriptor(element, parentAct, getConfig());
		if (foundDes instanceof Descriptor) {
			return (Descriptor) foundDes;
		}
		
		foundDes = ProcessCommandUtil.getInheritedDescriptor(element, parentAct, getConfig());
		if (foundDes instanceof Descriptor) {
			return (Descriptor) foundDes;
		}
		
		Descriptor descriptor = null;
		if (element instanceof Role) {
			RoleDescriptor rd = UmaFactory.eINSTANCE.createRoleDescriptor();
			rd.setRole((Role) element);
			descriptor = rd;
			
		} else if (element instanceof Task) {
			TaskDescriptor td = UmaFactory.eINSTANCE.createTaskDescriptor();
			td.setTask((Task) element);
			descriptor = td;
			
		} else if (element instanceof WorkProduct) {
			WorkProductDescriptor wpd = UmaFactory.eINSTANCE.createWorkProductDescriptor();
			wpd.setWorkProduct((WorkProduct) element);
			descriptor = wpd;
		}
		
		if (debug) {
			System.out.println("LD> Creating descriptor: " + descriptor); //$NON-NLS-1$
		}
		
		if (descriptor == null) {
			return null;
		}
		
		DescriptorPropUtil.getDesciptorPropUtil().setCreatedByReference(descriptor, true);
			
		String presentationName = element.getPresentationName();
		descriptor.setName(element.getName());
		descriptor.setPresentationName(StrUtil.isBlank(presentationName) ? element
				.getName() : presentationName);
		String guid = UmaUtil.generateGUID();
		descriptor.setBriefDescription(element.getBriefDescription());

		addToProcess(parentAct, descriptor, feature);	
		
		return descriptor;
	}
	
	private void addToProcess(Activity parent, Descriptor referencedDes,
			EReference feature) {
		UmaPackage up = UmaPackage.eINSTANCE;
		ProcessPackage pkg = (ProcessPackage) parent.eContainer();

		boolean oldParentDeliver = parent.eDeliver();
		boolean oldPkgDeliver = pkg.eDeliver();
		boolean oldReferencedDesDeliver = referencedDes.eDeliver();
		parent.eSetDeliver(false);
		pkg.eSetDeliver(false);

		try {
			parent.getBreakdownElements().add(referencedDes);
			pkg.getProcessElements().add(referencedDes);

			if (feature == up.getWorkProductDescriptor_DeliverableParts()) {
				referencedDes.eSetDeliver(false);
				referencedDes.setSuperActivities(null);
			}
		} finally {
			parent.eSetDeliver(oldParentDeliver);
			pkg.eSetDeliver(oldPkgDeliver);
			if (referencedDes.eDeliver() != oldReferencedDesDeliver) {
				referencedDes.eSetDeliver(oldReferencedDesDeliver);
			}
		}

	}
	
	public void updateProcessModel(Process proc) {
		clearCacheData();
		setCaching(true);
		updateProcessModel(proc, new HashSet<Activity>());
		clearCacheData();
		setCaching(false);
	}
	
	public void elementUpdateProcessModel(Process proc,
			Set<MethodElement> changedElementSet) {

		Set<Activity> actCollectedSet = new HashSet<Activity>();
		collectActivitiesToUpdate(proc, actCollectedSet,
				new HashSet<Activity>(), changedElementSet);
		Set<Activity> updatedActSet = new HashSet<Activity>();
		clearCacheData();
		setCaching(true);
		for (Activity act : actCollectedSet) {
			this.updateModelImpl(act, updatedActSet, false);
		}
		clearCacheData();
		setCaching(false);		
	}
	
	private void collectActivitiesToUpdate(Activity act,
			Set<Activity> actCollectedSet, Set<Activity> actProcessedSet,
			Set<MethodElement> changedElementSet) {
		if (actProcessedSet.contains(act)) { // extra precaution to prevent infinite loop
			return;
		}
		actProcessedSet.add(act);
		
		Activity baseAct = (Activity) act.getVariabilityBasedOnElement();
		if (baseAct != null) {
			collectActivitiesToUpdate(baseAct, actCollectedSet, actProcessedSet, changedElementSet);
		}

		List<BreakdownElement> beList = act.getBreakdownElements();
		for (int i = 0; i < beList.size(); i++) {
			BreakdownElement be = beList.get(i);
			if (be instanceof Descriptor && !actCollectedSet.contains(act)) {
				MethodElement element = getLinkedElement((Descriptor) be);
				if (changedElementSet.contains(element)) {
					actCollectedSet.add(act);

				} else if (be instanceof Descriptor) {
					if (changedElementSet.contains(be)) {
						actCollectedSet.add(act);
					}
				}
			} else if (be instanceof Activity) {
				collectActivitiesToUpdate((Activity) be, actCollectedSet,
						actProcessedSet, changedElementSet);
			}
		}
	}

	private void updateProcessModel(Process proc, Set<Activity> updatedActSet) {
		if (! ProcessUtil.isSynFree()) {
			if (! ProcessScopeUtil.getInstance().isConfigFree(proc)) {
				return;
			}
		}
		if (! canBeAutoSyned(proc)) {
			return;
		}
		long time = 0;
		if (timing && localTiming) {
			time = System.currentTimeMillis();
		}
		updateModelImpl(proc, updatedActSet, true);
		if (timing && localTiming) {
			time = System.currentTimeMillis() - time;
			System.out.println("LD> updateModel: " + time); //$NON-NLS-1$
		}
	}
	
	public void updateActivityModel(Activity act) {
		if (act instanceof Process) {
			if (! canBeAutoSyned((Process) act)) {
				return;
			}			
		}

		clearCacheData();
		setCaching(true);
		updateModelImpl(act, new HashSet<Activity>(), false);
		clearCacheData();
		setCaching(false);
	}
	
	private void updateModelImpl(Activity act, Set<Activity> updatedActSet, boolean recursive) {
		if (updatedActSet.contains(act)) {
			return;
		}
		//System.out.println("LD> updateModelImpl, act: " + act);
		
		updatedActSet.add(act);
		Activity baseAct = (Activity) act.getVariabilityBasedOnElement();
		if (baseAct != null) {
			updateModelImpl(baseAct, updatedActSet, recursive);
		}
		if (! ProcessUtil.isSynFree()) {
			Process proc = ProcessUtil.getProcess(act);
			if (proc == null || ! ProcessScopeUtil.getInstance().isConfigFree(proc)) {
				return;
			}
		}
				
		if (config == null) {
			Process proc = ProcessUtil.getProcess(act);
			Scope scope = ProcessScopeUtil.getInstance().getScope(proc);
			if (scope != null) {
				dynamicConfig = scope;
			} else {
				dynamicConfig = LibraryService.getInstance()
						.getCurrentMethodConfiguration();
			}
		}
		
		DescriptorPropUtil propUtil = DescriptorPropUtil.getDesciptorPropUtil();
		
		Set<Descriptor> tdReferencedSet = new HashSet<Descriptor>();
		Set<Descriptor> seenSet = new HashSet<Descriptor>();
		List<Descriptor> rdwpdList = new ArrayList<Descriptor>();
		List<BreakdownElement> beList =  act.getBreakdownElements();
		Set<Descriptor> localUseSet = new HashSet<Descriptor>(); 
		for (int i = 0; i < beList.size(); i++) {
			BreakdownElement be = beList.get(i);
			if (be instanceof Activity) {
				if (recursive) {
					updateModelImpl((Activity) be, updatedActSet, recursive);
				}
				
			} else if (be instanceof TaskDescriptor) {
				TaskDescriptor td = (TaskDescriptor) be;
				Descriptor greenParent = propUtil.getGreenParentDescriptor(td);
				if (greenParent != null) {
					CustomizeDescriptorCommand.updateFromGreenParent(greenParent, td, false);
				}
				
				collectAllReferences(td, tdReferencedSet, seenSet);

			} else if (be instanceof RoleDescriptor) {
				RoleDescriptor rd = (RoleDescriptor) be;
				rdwpdList.add(rd);
				
			} else if (be instanceof WorkProductDescriptor) {
				WorkProductDescriptor wpd = (WorkProductDescriptor) be;
				rdwpdList.add(wpd);
			}
			
			if (be instanceof Descriptor) {
				localUseSet.addAll(propUtil.getLocalUsedDescriptors((Descriptor) be));
			}
		}
		
		Set<Descriptor> toRemovedSet = new HashSet<Descriptor>();
		for (Descriptor des : rdwpdList) {
			collectAllReferences(des, null, seenSet);
			
			if (des instanceof TaskDescriptor || localUseSet.contains(des) ||
					! propUtil.isCreatedByReference(des)) {
				continue;
			}
			if (!tdReferencedSet.contains(des)) {
//				act.getBreakdownElements().remove(des);
				toRemovedSet.add(des);
			}
		}
		for (Descriptor des : toRemovedSet) {
			if (! ProcessUtil.checkDescriptorReferences(toRemovedSet, des)) {
				act.getBreakdownElements().remove(des);
			}
		}
		
		beList =  act.getBreakdownElements();
		for (int i = 0; i < beList.size(); i++) {
			BreakdownElement be = beList.get(i);
			if (be instanceof Descriptor) {
				RealizedDescriptor rdes = (RealizedDescriptor) getRealizedElement(be);	
				rdes.updateStringValues();
			} else {
				RealizedBreakdownElement rBe = (RealizedBreakdownElement) getRealizedElement(be);
				rBe.updateAndGetAllReferenced();
				rBe.updateStringValues();
			}
		}
				
	}
	
	private void collectAllReferences(Descriptor des, Set<Descriptor> collectingSet, Set<Descriptor> seenSet) {
		if (seenSet.contains(des)) {
			return;
		}
		seenSet.add(des);
		
		RealizedDescriptor rdes = (RealizedDescriptor) getRealizedElement(des);
		Set<Descriptor> references = rdes.updateAndGetAllReferenced();
		if (collectingSet != null) {
			collectingSet.addAll(references);
		}
		for (Descriptor ref : references) {
			collectAllReferences(ref, collectingSet, seenSet);
		}
	}
	
	public void updateAllProcesseModels() {		
		boolean oldLocalTiming = localTiming;
		long time = 0;
		if (timing) {
			time = System.currentTimeMillis();
			localTiming = false;
		}

		Set<Activity> updatedActSet = new HashSet<Activity>();
		clearCacheData();
		setCaching(true);
		for (Process proc : LibraryEditUtil.getInstance().collectProcessesFromConfig(
				getConfig())) {
			updateProcessModel(proc, updatedActSet);
		}
		clearCacheData();
		setCaching(false);
		if (timing) {
			time = System.currentTimeMillis() - time;
			System.out.println("LD> beginPublish: " + time); //$NON-NLS-1$
			localTiming = oldLocalTiming;
		}
	}

	private boolean canBeAutoSyned(Process proc) {
		boolean ret = ConfigurationHelper.getDelegate().canBeConfigFree(proc);
		return ret;
	}
	
}
