//------------------------------------------------------------------------------
// 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.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
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.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>();
	
	public ConfigurationData(MethodConfiguration config) {
		this.config = config;
		
		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 void updateConfigChange() {
		if (! needUpdateConfigChange) {
			return;
		}
		
		updateCcMap(substractedCcMap, collectAll(config.getSubtractedCategory()), substractedElemMap);
		updateCcMap(addedCcMap, collectAll(config.getAddedCategory()), addedElemMap);
		
		needUpdateConfigChange = false;
	}
	
	private Collection<ContentCategory> collectAll(Collection<ContentCategory> ccList) {
		if (ccList == null || ccList.isEmpty()) {
			return null;
		}
		Set<ContentCategory> all = new LinkedHashSet<ContentCategory>();		
		collectAll(ccList, all);
		return all;
	}
	
	private void collectAll(Collection<ContentCategory> ccList, Set<ContentCategory> all) {
		if (ccList == null || ccList.isEmpty()) {
			return;
		}
		for (Iterator<ContentCategory> it = ccList.iterator(); it.hasNext();) {
			ContentCategory cc = it.next();
			if (! all.contains(cc)) {
				all.add(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) {
			return ((RoleSet) cc).getRoles();
		}
		if (cc instanceof RoleSetGrouping) {
			return ((RoleSetGrouping) cc).getRoleSets();
		}
		if (cc instanceof Tool) {
			return ((Tool) cc).getToolMentors();
		}
		if (cc instanceof WorkProductType) {
			return ((WorkProductType) cc).getWorkProducts();
		}
		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) {
		//return cc.getCategorizedElements();
		return null;
	}
	
	private void incOrDecElemMap(Map<String, MethodElementData> map, 
						Collection<MethodElement> elements, boolean inc) {
		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;
		}
		
		//refresh cache info
		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;
			}
		}
		
		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 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.ADD
							|| 	type == Notification.ADD_MANY
							|| 	type == Notification.REMOVE
							||  type == Notification.REMOVE_MANY) {					
						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;
		}
	}
	
}
