//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 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.configuration;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.ContentCategory;
import org.eclipse.epf.uma.CustomCategory;
import org.eclipse.epf.uma.Discipline;
import org.eclipse.epf.uma.DisciplineGrouping;
import org.eclipse.epf.uma.Domain;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.MethodPackage;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.ProcessPackage;
import org.eclipse.epf.uma.RoleSet;
import org.eclipse.epf.uma.RoleSetGrouping;
import org.eclipse.epf.uma.Tool;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.VariabilityType;
import org.eclipse.epf.uma.WorkProductType;

/**
 *  Class managing configuration data calculation and cache
 * 
 * @author Weiping Lu - Mar 20, 2007
 * @since 1.2
 */
public class ConfigurationData {

	public static boolean active = false;	//temp flag to be removed
	
	private MethodConfiguration config;
	private Map<String, MethodElementData> substractedElemMap = new HashMap<String, MethodElementData>();
	private Map<String, MethodElementData> addedElemMap = new HashMap<String, MethodElementData>();;
	private Map<String, ContentCategoryData> substractedCcMap = new HashMap<String, ContentCategoryData>();
	private Map<String, ContentCategoryData> addedCcMap = new HashMap<String, ContentCategoryData>();
	private boolean needUpdateConfigChange = true;
	private Set<ContentCategory> changedContentCategorySet = new HashSet<ContentCategory>();
	private Map<String, ContentCategory> originalSubstracted;
	private Map<String, ContentCategory> orignalAdded;
	
	public ConfigurationData(MethodConfiguration config) {
		this.config = config;
		
		//-> Temp test
		
		
		
		
		
		//<- Temp test
				
		Adapter configListener = new AdapterImpl() {
			public void notifyChanged(Notification msg) {
				int type = msg.getEventType();
				if (		type == Notification.ADD
						|| 	type == Notification.ADD_MANY
						|| 	type == Notification.REMOVE
						||  type == Notification.REMOVE_MANY) {					
					needUpdateConfigChange = true;
					changedContentCategorySet = null;
				}
			}
		};
		config.eAdapters().add(configListener);
	}	
	
	private boolean getUpdatingConfigChange() {
		return originalSubstracted != null && orignalAdded != null;
	}
	
	private void updateConfigChange() {
		if (! needUpdateConfigChange) {
			return;
		}
		if (getUpdatingConfigChange()) {
			return;			
		}		
		
		originalSubstracted = collectAll(config.getSubtractedCategory());
		orignalAdded = collectAll(config.getAddedCategory());		
		
		Map<String, ContentCategory> calSubstracted = handleReplacers(originalSubstracted, true);
		Map<String, ContentCategory> calAdded = handleReplacers(orignalAdded, false);
		handleContributors(calSubstracted, true);
		handleContributors(calAdded, false);
		
		updateCcMap(addedCcMap, calSubstracted.values(), addedElemMap);
		updateCcMap(substractedCcMap, calAdded.values(), substractedElemMap);
		
		needUpdateConfigChange = false;		
		
		originalSubstracted = null;		//not needed after update
		orignalAdded = null;			//not needed after update
	}
		
	private void handleContributors(Map<String, ContentCategory> map,  boolean substracted) {
		if (! substracted) {
			return;
		}
		List<ContentCategory> addedList = new ArrayList<ContentCategory>();
				
		for (Iterator<ContentCategory> it = map.values().iterator(); it.hasNext();) {
			ContentCategory cc = it.next();
			List<ContentCategory> contributers = ConfigurationHelper.getContributors(cc, config);
			addedList.addAll(contributers);
		}
		for (Iterator<ContentCategory> it = addedList.iterator(); it.hasNext();) {
			ContentCategory cc = it.next();
			map.put(cc.getGuid(), cc);
		}		
	}
	
	private Map<String, ContentCategory> handleReplacers(Map<String, ContentCategory> originals, boolean substracted) {
		if (originals == null || originals.isEmpty()) {
			return originals;
		}
		
		Map<String, ContentCategory> ret = new HashMap<String, ContentCategory>();
		
		for (Iterator<ContentCategory> it = originals.values().iterator(); it.hasNext();) {
			ContentCategory cc = it.next();
			VariabilityElement replacer = ConfigurationHelper.getReplacer(cc, config);
			boolean toKeep = true;
			if (replacer != null) {
				toKeep = false;
				
				VariabilityElement nestedReplacer = replacer;
				while (nestedReplacer != null) {
					replacer = nestedReplacer;
					nestedReplacer = ConfigurationHelper.getReplacer(nestedReplacer, config);
				}
				if (substracted) {
					if (originalSubstracted.containsKey(replacer.getGuid())) {
						toKeep = true;
					}
				}
			}
			if (toKeep) {
				ret.put(cc.getGuid(), cc);
			}			

		}
		return ret;
	}			
	
	private Map<String, ContentCategory> collectAll(Collection<ContentCategory> ccList) {
		if (ccList == null || ccList.isEmpty()) {
			return null;
		}
		Map<String, ContentCategory> all = new LinkedHashMap<String, ContentCategory>();		
		collectAll(ccList, all);
		return all;
	}
	
	private void collectAll(Collection<ContentCategory> ccList, Map<String, ContentCategory> all) {
		if (ccList == null || ccList.isEmpty()) {
			return;
		}
		for (Iterator<ContentCategory> it = ccList.iterator(); it.hasNext();) {
			ContentCategory cc = it.next();
			if (! all.containsKey(cc.getGuid())) {
				all.put(cc.getGuid(), cc);
				collectAll(getChildCC(cc), all);
			}
		}
	}	
	
	private Collection<ContentCategory> getChildCC(ContentCategory cc) {
		if (cc instanceof CustomCategory) {
			return ((CustomCategory) cc).getSubCategories();
		}
		if (cc instanceof Discipline) {
			return ((Discipline) cc).getSubdiscipline();
		}
		if (cc instanceof DisciplineGrouping) {
			return ((DisciplineGrouping) cc).getDisciplines();
		}
		if (cc instanceof Domain) {
			return ((Domain) cc).getSubdomains();
		}
		if (cc instanceof RoleSet) {
		}
		if (cc instanceof RoleSetGrouping) {
			return ((RoleSetGrouping) cc).getRoleSets();
		}
		if (cc instanceof Tool) {
			return ((Tool) cc).getToolMentors();
		}
		if (cc instanceof WorkProductType) {
		}
		return null;
	}	
	
	
	private void updateCcMap(Map<String, ContentCategoryData> map, Collection<ContentCategory> ccList,
			Map<String, MethodElementData> ccDataOwner) {
		if (ccList == null || ccList.isEmpty()) {
			return;
		}
		Map<String, ContentCategoryData> newMap = new HashMap<String, ContentCategoryData>();
		
		boolean changed = false;
		for (Iterator<ContentCategory> it = ccList.iterator(); it.hasNext();) {
			ContentCategory cc = it.next();
			ContentCategoryData ccData = map == null ? null : map.get(cc
					.getGuid());
			if (ccData == null) {
				ccData = new ContentCategoryData(cc, ccDataOwner);
				changed = true;
			}
			newMap.put(cc.getGuid(), ccData);
		}

		for (Iterator<Map.Entry<String, ContentCategoryData>> it = map
				.entrySet().iterator(); it.hasNext();) {
			Map.Entry<String, ContentCategoryData> entry = it.next();
			String guid = entry.getKey();
			ContentCategoryData ccData = entry.getValue();
			
			if (!newMap.containsKey(guid)) {
				changed = true;
				incOrDecElemMap(ccDataOwner, getElements(ccData.getContentCategory()), false);
			}
		}
		
		if (changed) {
			map = newMap;
		}
	}	
	
	private void updateCcChanges() {
		if (changedContentCategorySet == null) {
			return;
		}
		for (Iterator<ContentCategory> it = changedContentCategorySet.iterator(); it.hasNext(); ) {
			ContentCategory cc = it.next();
			updateCcChange(substractedCcMap, cc);
			updateCcChange(addedCcMap, cc);
		}
		changedContentCategorySet = null;
	}				

	private void updateCcChange(Map<String, ContentCategoryData> map, ContentCategory cc) {
		ContentCategoryData ccData = map == null ? null : map.get(cc.getGuid());
		if (ccData == null) {
			return;
		}
		assert(ccData.getContentCategory() == cc);
		ccData.updateElementMap();
	}		

	//No duplicates in the returned elements
	private Collection<MethodElement> getElements(ContentCategory cc) {
		Collection<MethodElement> elements = new ArrayList<MethodElement>();
		elements.addAll(cc.getAssets());
		elements.addAll(cc.getChecklists());
		elements.addAll(cc.getConceptsAndPapers());
		elements.addAll(cc.getExamples());
		elements.addAll(cc.getGuidelines());
		elements.addAll(cc.getSupportingMaterials());		
		
		if (cc instanceof CustomCategory) {
			elements.addAll(((CustomCategory) cc).getSubCategories());
			elements.addAll(((CustomCategory) cc).getCategorizedElements());
		}
		else if (cc instanceof Discipline) {
			elements.addAll(((Discipline) cc).getReferenceWorkflows());
			elements.addAll(((Discipline) cc).getSubdiscipline());
			elements.addAll(((Discipline) cc).getTasks());
		}
		else if (cc instanceof DisciplineGrouping) {
			elements.addAll(((DisciplineGrouping) cc).getDisciplines());
		}
		else if (cc instanceof Domain) {
			elements.addAll(((Domain) cc).getSubdomains());
			elements.addAll(((Domain) cc).getWorkProducts());
		}
		else if (cc instanceof RoleSet) {
			elements.addAll(((RoleSet) cc).getRoles());
		}
		else if (cc instanceof RoleSetGrouping) {
			elements.addAll(((RoleSetGrouping) cc).getRoleSets());
		}
		else if (cc instanceof Tool) {
			elements.addAll(((Tool) cc).getToolMentors());
		}
		else if (cc instanceof WorkProductType) {
			elements.addAll(((WorkProductType) cc).getWorkProducts());
		}

		return getUniqueCollection(elements);
	}
	
	private Collection<MethodElement> getUniqueCollection(Collection<MethodElement> elements) {
		Collection<MethodElement> ret = new LinkedHashSet<MethodElement>();
		for (Iterator<MethodElement> it = elements.iterator(); it.hasNext();) {
			MethodElement element = it.next();
			if (! ret.contains(element)) {
				ret.add(element);
			}
		}
		return ret;
	}
	
	
	private void incOrDecElemMap(Map<String, MethodElementData> map, 
						Collection<MethodElement> elements, boolean inc) {
		if (elements == null || elements.isEmpty()) {
			return;
		}
		for (Iterator<MethodElement> it = elements.iterator(); it.hasNext();) {
			incOrDecElemMap(map, it.next(), inc);
		}
	}
	
	private void incOrDecElemMap(Map<String, MethodElementData> map, MethodElement element, 
			boolean inc) {
		if (map == null) {
			return;
		}

		MethodElementData data = map.get(element.getGuid());
		if (data != null) {
			assert (element == data.element);
			assert (data.refCount > 0);

			if (inc) {
				data.refCount++;
			} else {
				data.refCount--;
				if (data.refCount == 0) {
					map.remove(element.getGuid());
				}
			}
			return;
		} else if (!inc) {
			return;
		}

		map.put(element.getGuid(), new MethodElementData(element));
	}
	
	public boolean isOwnerSelected(MethodElement element, boolean checkSubtracted) {
		if (element == null) {
			return false;
		}

		if (ConfigurationHelper.isDescriptionElement(element)) {
			return true;
		}
		
		if (getUpdatingConfigChange()) {
			if (originalSubstracted.containsKey(element.getGuid()) || 
				orignalAdded.containsKey(element.getGuid())) {
				return true;
			}			
		} else {
			updateConfigChange();
			updateCcChanges();
			
			// since UMA 1.0.4, configuration can have added categories 
			// and subtracted categories. The order of filtering is:
			// 1. any element in the subtracted categories should be excluded
			// 2. any element in the added categories should be included
			// 3. any element not in the selected package or plugin should be excluded.		
			if ( checkSubtracted) {
				if (substractedElemMap.containsKey(element.getGuid())) {
					return false;
				} else if (element instanceof VariabilityElement){
					if (contributedBaseInSubstracted((VariabilityElement) element)) {
						return false;
					}
				}
			}
			
			if (addedElemMap.containsKey(element.getGuid())) {
				return true;
			}
		} 
		
		// elements beyond configuration scope should be always visible
		if ((element instanceof MethodLibrary)
				|| (element instanceof MethodConfiguration)) {
			return true;
		} else if (element instanceof MethodPlugin) {
			List plugins = config.getMethodPluginSelection();
			return (plugins != null) && plugins.contains(element);
		} else {
			// if the ownerprocess can't show, can't accept
			if (element instanceof Activity) {
				Activity base = (Activity) ((Activity) element)
						.getVariabilityBasedOnElement();
				if (base != null && base != element) {
					MethodElement owningProc = TngUtil.getOwningProcess(base);
					if ( owningProc != null && owningProc != element 
							&& !ConfigurationHelper.inConfig(owningProc, config, checkSubtracted)) {
						return false;
					}
				}
			}

			EObject pkg = LibraryUtil.getSelectable(element);

			// accept global package if the plugin is in the configuration
			if (pkg instanceof MethodPackage
					&& ConfigurationHelper.isGlobalPackage((MethodPackage) pkg)) {
				MethodPlugin plugin = LibraryUtil.getMethodPlugin(pkg);
				return ConfigurationHelper.inConfig(plugin, config, checkSubtracted);
			}

			List pkgs = config.getMethodPackageSelection();
			if (pkgs == null) {
				return false;
			}

			// per Phong's request, for ProcessPackage, check the
			// ProcessComponent parent instead
			if (pkg instanceof ProcessPackage) {
				while ((pkg != null) && !(pkg instanceof ProcessComponent)
						&& !pkgs.contains(pkg)) {
					pkg = pkg.eContainer();
				}
			}

			// if package not selected, return false
			if ((pkg == null) || !pkgs.contains(pkg)) {
				return false;
			}

			return true;
		}
	}

	private boolean contributedBaseInSubstracted(VariabilityElement ve) {
		if (ve.getVariabilityType() != VariabilityType.CONTRIBUTES_LITERAL) {
			return false;
		}
		
		VariabilityElement base = ve.getVariabilityBasedOnElement();
		if (base == null) {
			return false;
		}
		
		if (substractedElemMap.containsKey(base.getGuid())) {
			return true;
		}
		
		if (ConfigurationHelper.inConfig(base, config, true)) {
			return contributedBaseInSubstracted(base);
		}

		return false;
	}	
	
	private class ContentCategoryData {
		private ContentCategory contentCategory;
		private Map<String, MethodElement> elementMap = new HashMap<String, MethodElement>();
		private Map<String, MethodElementData> dataMap;
		
		public ContentCategoryData(ContentCategory cc, Map<String, MethodElementData> dataMap) {
			contentCategory = cc;
			
			Adapter ContentCategoryListener = new AdapterImpl() {
				public void notifyChanged(Notification msg) {
					int type = msg.getEventType();
					if (type == Notification.SET) {
						//to do: check any variability change
						//msg.getFeature();
						needUpdateConfigChange = true;
					}
								
					if (needUpdateConfigChange) {
						return;
					}						
					changedContentCategorySet.add(contentCategory);
				}
			};			
			contentCategory.eAdapters().add(ContentCategoryListener);
			
			this.dataMap = dataMap;
			updateElementMap();
		}
		
		public ContentCategory getContentCategory() {
			return contentCategory;
		}
		
		public void updateElementMap() {

			Map<String, MethodElement> newMap = new HashMap<String, MethodElement>();
			Collection<MethodElement> elementList = getElements(contentCategory);

			boolean changed = false;
			for (Iterator<MethodElement> it = elementList.iterator(); it
					.hasNext();) {
				MethodElement element = it.next();
				if (elementMap == null
						|| !elementMap.containsKey(element.getGuid())) {
					changed = true;
					incOrDecElemMap(dataMap, element, true);
				}
				newMap.put(element.getGuid(), element);
			}

			for (Iterator<Map.Entry<String, MethodElement>> it = elementMap
					.entrySet().iterator(); it.hasNext();) {
				Map.Entry<String, MethodElement> entry = it.next();
				String guid = entry.getKey();
				MethodElement element = entry.getValue();
				if (!newMap.containsKey(guid)) {
					changed = true;
					incOrDecElemMap(dataMap, element, false);
				}
			}

			if (changed) {
				elementMap = newMap;
			}

		}		
				
	}
	
	private class MethodElementData {
		public MethodElement element;
		public int refCount;
		
		public MethodElementData(MethodElement e) {
			element = e;
			refCount = 1;
		}
	}
	
}
