//------------------------------------------------------------------------------
// 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.configuration;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
import org.eclipse.epf.library.edit.IConfigurator;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.VariabilityInfo;
import org.eclipse.epf.library.edit.configuration.CategoriesItemProvider;
import org.eclipse.epf.library.edit.realization.IRealizationManager;
import org.eclipse.epf.library.edit.util.LibraryEditUtil;
import org.eclipse.epf.library.edit.util.MethodElementPropUtil;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.library.util.Log;
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.MethodPackage;
import org.eclipse.epf.uma.Role;
import org.eclipse.epf.uma.RoleSet;
import org.eclipse.epf.uma.RoleSetGrouping;
import org.eclipse.epf.uma.Task;
import org.eclipse.epf.uma.Tool;
import org.eclipse.epf.uma.ToolMentor;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.WorkProduct;
import org.eclipse.epf.uma.WorkProductType;
import org.eclipse.epf.uma.util.AssociationHelper;
import org.eclipse.epf.uma.util.Scope;

/**
 * A method configuration filter to allow filtering element 
 * and realize the element feature values within a configuration.
 * 
 * @author Phong Nguyen Le
 * @author Jinhua Xi
 * @since 1.0
 */
public class ConfigurationFilter extends AdapterImpl implements IConfigurator {

	protected MethodConfiguration methodConfig;	
	//private Viewer viewer;
	
	// set the default behavior for configuration view to true, i.e. contributors are discarded.
	private boolean discardContributors = true;
	

	/**
	 * constructor
	 * @param methodConfig a <code>MethodConfiguration</code>
	 * @param viewer a <code>Viewer</code>
	 */
	public ConfigurationFilter(MethodConfiguration methodConfig) {
		this.methodConfig = methodConfig;
		//this.viewer = viewer;
	}

	public ConfigurationFilter(MethodConfiguration methodConfig, boolean discardContributors) {
		this(methodConfig);
		this.discardContributors = discardContributors;
	}
	
	/**
	 * @see org.eclipse.epf.library.edit.IFilter#accept(java.lang.Object)
	 */
	public boolean accept(Object obj) {
		if (methodConfig == null)
			return true;
		
		obj = LibraryUtil.unwrap(obj);

		if (methodConfig instanceof Scope && obj instanceof MethodElement) {
			return ((Scope) methodConfig).inScope((MethodElement) obj);
		}
		
		if ( (ElementRealizer.isExtendReplaceEnabled() ||  
				(obj instanceof VariabilityElement) && ConfigurationHelper.isExtendReplacer((VariabilityElement)obj) )
				&& FeatureValue.isBlankIndicator(obj) ) {
			return false;
		}
		
		if (obj instanceof MethodPackage) {
			return methodConfig.getMethodPackageSelection().contains(obj);
		} else if (obj instanceof MethodElement) {
			return ConfigurationHelper.canShow((MethodElement) obj,
					methodConfig);
		} else if (obj instanceof ItemProviderAdapter) {
			return true;
		} else {
			if (Log.DEBUG) {
				System.out
						.println("Object filtered: " + (obj == null ? null : obj.toString())); //$NON-NLS-1$
			}
		}
		return false;
	}
	

	/**
	 * get the realized children for the given object and feature
	 * 
	 * @param obj Object
	 * @param childFeature EStructuralFeature
	 * 
	 * @return Collection
	 */
	public Collection getChildren(Object obj, EStructuralFeature childFeature) {
		if (methodConfig == null)
			return null;

		ElementRealizer realizer = DefaultElementRealizer.newElementRealizer(methodConfig);
		// discard the contributors
		realizer.setDiscardContributor(this.discardContributors);

		if (childFeature != null && childFeature.isMany()) {
			if (obj instanceof MethodElement) {
				List value = ConfigurationHelper.calc0nFeatureValue(
						(MethodElement) obj, childFeature, realizer);
				return value;
			}
		}

		return null;
	}

	/**
	 * @see org.eclipse.emf.common.notify.impl.AdapterImpl#notifyChanged(org.eclipse.emf.common.notify.Notification)
	 */
//	public void notifyChanged(final Notification msg) {
//		if (viewer == null) {
//			return;
//		}
//
//		SafeUpdateController.syncExec(new Runnable() {
//			public void run() {
//				switch (msg.getEventType()) {
//				case Notification.ADD:
//				case Notification.ADD_MANY:
//				case Notification.REMOVE:
//				case Notification.REMOVE_MANY:
//					viewer.refresh();
//				}
//			}
//		});
//
//	}

	/**
	 * @see org.eclipse.epf.library.edit.IConfigurator#getMethodConfiguration()
	 */
	public MethodConfiguration getMethodConfiguration() {
		return methodConfig;
	}

	/**
	 * @see org.eclipse.epf.library.edit.IConfigurator#setMethodConfiguration(org.eclipse.epf.uma.MethodConfiguration)
	 */
	public void setMethodConfiguration(MethodConfiguration config) {
		methodConfig = config;
	}

	protected void resolveElementVariabilityList(VariabilityElement element,
			VariabilityInfo info, boolean includeBase, ElementRealizer realizer) {

		if (methodConfig == null) {
			return;
		}
		
		//resolve to include contributors
		resolveElementContributors(element,info,realizer);

		// if the element is an extended element, get the base element's
		// contributors
		// NOTE: the base element itself should not be included since it's
		// already handled
		// in the activity realiztion in ItemProviders.
		if (ConfigurationHelper.isExtender(element)) {
			MethodElement base = element.getVariabilityBasedOnElement();
			VariabilityElement e = (VariabilityElement) ConfigurationHelper
					.getCalculatedElement(base, realizer);

			// if includebase is true, add the element to the inheritance list
			if (includeBase) {
				List values = info.getInheritanceList();
				if (!values.contains(e)) {
					values.add(e);
				}
			}

			// resolve the base to include additional contributors and/or base
			resolveElementVariabilityList(e, info, includeBase, realizer);

		}

	}
	
	protected void resolveElementContributors(VariabilityElement element,
			VariabilityInfo info, ElementRealizer realizer){
		// if the element has contributors in the configuration, get the
		// reference properties
		// if a contributor has replacer, it's replacer is used
		List items = ConfigurationHelper.getContributors(element, methodConfig);
		if (items != null && items.size() > 0) {
			for (Iterator it = items.iterator(); it.hasNext();) {
				VariabilityElement e = (VariabilityElement) it.next();
				List values = info.getContributors();
				if (!values.contains(e)) {
					values.add(e);
				}
				resolveElementVariabilityList(e, info, false, realizer);
			}
		}
	}

	/*
	 * resolve the variability of the element and get a list of contributors.
	 * 
	 * This method is used for realizing actitivy breakdown elements in the
	 * itemProviders.
	 * 
	 * @see org.eclipse.epf.library.edit.IConfigurator#getVariabilityInfo(org.eclipse.epf.uma.VariabilityElement)
	 */
	public VariabilityInfo getVariabilityInfo(VariabilityElement ve) {

		// calculate the element first
		ElementRealizer realizer = DefaultElementRealizer.newElementRealizer(methodConfig, true, true);
		return getVariabilityInfo(ve, realizer);
	}

	protected VariabilityInfo getVariabilityInfo(VariabilityElement ve, ElementRealizer realizer) {

		// calculate the element first
		VariabilityElement e = (VariabilityElement) ConfigurationHelper
				.getCalculatedElement(ve, realizer);

		if (e == null) {
			return null;
		}

		VariabilityInfo info = new VariabilityInfo(ve);
		info.getInheritanceList().add(e);

		resolveElementVariabilityList(e, info, true, realizer);

		return info;
	}
	
	public Object resolve(Object element) {
		if (element instanceof VariabilityElement) {
			ElementRealizer realizer = DefaultElementRealizer.newElementRealizer(methodConfig, true, true);
			return ConfigurationHelper.getCalculatedElement(
					(MethodElement) element, realizer);
		}
		return element;
	}
	
	
	/**
	 * get filter for uncategorized tasks
	 * 
	 * @return IFilter
	 */
	public IFilter getUncategorizedTaskFilter() {
		return new IFilter() {
			public boolean accept(Object obj) {
				// 158924 - wrong categories in configuration view
				// should use the default realizer
				// we should not discard the discipline contributors 
				// instead should realize to the base discipline
				return ( obj instanceof Task ) && 
					ConfigurationHelper.calc0nFeatureValue(
							(Task)obj, 
							AssociationHelper.Task_Disciplines, 
							DefaultElementRealizer.newElementRealizer(methodConfig)).isEmpty();					
			}
		};
	}
	
	/**
	 * get filter for workproducts without a domain
	 * 
	 * @return IFilter
	 */
	public IFilter getDomainUncategorizedWorkProductFilter(){
		return new IFilter() {
			public boolean accept(Object obj) {
				// 158924 - wrong categories in configuration view
				// should use the default realizer
				// we should not discard the domain contributors 
				// instead should realize to the base domain
				return ( obj instanceof WorkProduct ) && 
					ConfigurationHelper.calc0nFeatureValue(
							(WorkProduct)obj, 
							AssociationHelper.WorkProduct_Domains, 
							DefaultElementRealizer.newElementRealizer(methodConfig)).isEmpty();					
			}
		};
	}
	
	/**
	 * get filter for workproducts without a WP Type
	 * 
	 * @return IFilter
	 */
	public IFilter getWpTypeUncategorizedWorkProductFilter(){
		return new IFilter() {
			public boolean accept(Object obj) {
				// 158924 - wrong categories in configuration view
				// should use the default realizer
				// we should not discard the WPType contributors 
				// instead should realize to the base 
				return ( obj instanceof WorkProduct ) && 
					ConfigurationHelper.calc0nFeatureValue(
							(WorkProduct)obj, 
							AssociationHelper.WorkProduct_WorkProductTypes, 
							DefaultElementRealizer.newElementRealizer(methodConfig)).isEmpty();					
			}
		};
	}
	
	/**
	 * get filter for uncategorized roles
	 * 
	 * @return IFilter
	 */
	public IFilter getUncategorizedRoleFilter(){
		return new IFilter() {
			public boolean accept(Object obj) {
				// 158924 - wrong categories in configuration view
				// should use the default realizer
				// we should not discard the roleset contributors 
				// instead should realize to the base 
				return ( obj instanceof Role ) && 
					ConfigurationHelper.calc0nFeatureValue(
							(Role)obj, 
							AssociationHelper.Role_RoleSets, 
							DefaultElementRealizer.newElementRealizer(methodConfig)).isEmpty();					
			}
		};
	}

	/**
	 * get filter for uncategorized tool mentors
	 * 
	 * @return IFilter
	 */
	public IFilter getUncategorizedToolMentorFilter() {
		return new IFilter() {
			public boolean accept(Object obj) {
				// 158924 - wrong categories in configuration view
				// should use the default realizer
				// we should not discard the tool contributors 
				// instead should realize to the base 
				return ( obj instanceof ToolMentor ) && 
					ConfigurationHelper.calc0nFeatureValue(
							(ToolMentor)obj, 
							AssociationHelper.ToolMentor_Tools, 
							DefaultElementRealizer.newElementRealizer(methodConfig)).isEmpty();					
			}
		};
	}
	
	/**
	 * get filter for disciplines and displine groupings
	 * 
	 * @return IFilter
	 */
	public IFilter getDisciplinesFilter() {
		return new IFilter() {
			public boolean accept(Object obj) {
				// [Bug 162603] New: Replacing disciplines do appear inside their replaced elements discipline groupings 
				// as well as outside of the discipline grouping
				if ( obj instanceof DisciplineGrouping ) {
					return true;
				}
				
				return ( obj instanceof Discipline ) && 
				ConfigurationHelper.calc0nFeatureValue(
						(MethodElement)obj, 
						AssociationHelper.Discipline_DisciplineGroupings, 
						DefaultElementRealizer.newElementRealizer(methodConfig)).isEmpty();					
			}
		};
	}
	
	/**
	 * get filter for rolesets and roleset groupings
	 * 
	 * @return IFilter
	 */
	public IFilter getRoleSetsFilter() {
		return new IFilter() {
			public boolean accept(Object obj) {
				// [Bug 162603] New: Replacing disciplines do appear inside their replaced elements discipline groupings 
				// as well as outside of the discipline grouping
				// same for roleset grouping
				if ( obj instanceof RoleSetGrouping ) {
					return true;
				}
				
				return ( obj instanceof RoleSet ) && 
					ConfigurationHelper.calc0nFeatureValue(
							(MethodElement)obj, 
							AssociationHelper.RoleSet_RoleSetGrouppings, 
							DefaultElementRealizer.newElementRealizer(methodConfig)).isEmpty();					
			}
		};
	}
	
	/**
	 * @return an IRealizationManager instance
	 */
	public IRealizationManager getRealizationManager() {
		MethodConfiguration c = getMethodConfiguration();
		return ConfigurationHelper.getDelegate().getRealizationManager(c);
	}
	
	public Collection<?> getModifiedChildren(Object parentObject, Collection children) {
		if (ConfigurationHelper.getDelegate().isAuthoringMode()) {
			return children;
		}		
		if (ConfigurationHelper.getDelegate().isPublishingMode()) {
			return children;
		}
		if (children == null || children.isEmpty()) {
			return children;			
		}
		
		boolean modified = false;
		List modifiedChildren = new ArrayList();
		if (parentObject instanceof CategoriesItemProvider || TngUtil.unwrap(parentObject) instanceof ContentCategory) {
			for (Object child : children) {
				if (child instanceof ContentCategory) {
					if (! isEmpty((ContentCategory) child)) {
						modifiedChildren.add(child);
					} else {
						modified = true;
					}
				} else {
					modifiedChildren.add(child);
				}
			}
		}		
		return modified ? modifiedChildren : children;
	}
	
	public boolean isEmpty(ContentCategory cc) {
		return isEmpty(cc, new HashMap<ContentCategory, Boolean>());
	}
	
	public static Object isEmptyCheckLock = new Object();
	
	private boolean isEmpty(ContentCategory cc, Map<ContentCategory, Boolean> processedMap) {
		Boolean bvalue = processedMap.get(cc);
		if (bvalue == null) {
			Map map = MethodElementPropUtil.getMethodElementPropUtil().getExtendedPropertyMap(cc, true);
			try {
				map.put(isEmptyCheckLock, true);
				boolean b = isEmpty_(cc, processedMap);
				bvalue = b ? Boolean.TRUE : Boolean.FALSE;
				processedMap.put(cc, bvalue);
			} finally {
				map.remove(isEmptyCheckLock);
			}
		}		
		return bvalue.booleanValue();
	}
	
	private boolean isEmpty_(ContentCategory cc, Map<ContentCategory, Boolean> processedMap) {
		LibraryEditUtil util = LibraryEditUtil.getInstance();
		
		EReference ref = getCategorizedRef(cc);
		Object value = ref == null ? null : util.calc0nFeatureValue(cc, ref, getMethodConfiguration());
		if (value instanceof List) {
			for (Object item : (List) value) {
				if (! (item instanceof ContentCategory)) {
					return false;
				}
			}
		}

		ref = getSubCategoryRef(cc);
		value = ref == null ? null : util.calc0nFeatureValue(cc, ref, getMethodConfiguration());
		if (value instanceof List) {
			for (Object item : (List) value) {
				if (item instanceof ContentCategory) {
					if (! isEmpty((ContentCategory) item, processedMap)) {
						return false;
					}
				}
			}
		}
		return true;
	}
	
	
	private EReference getSubCategoryRef(ContentCategory cc) {
		UmaPackage up = UmaPackage.eINSTANCE;
		if (cc instanceof CustomCategory) {
			return up.getCustomCategory_CategorizedElements();
		}
		if (cc instanceof Discipline) {
			return up.getDiscipline_Subdiscipline();
		}
		if (cc instanceof DisciplineGrouping) {
			return up.getDisciplineGrouping_Disciplines();
		}
		if (cc instanceof Domain) {
			return up.getDomain_Subdomains();
		}
		if (cc instanceof RoleSet) {
			return null;
		}
		if (cc instanceof RoleSetGrouping) {
			return up.getRoleSetGrouping_RoleSets();
		}
		if (cc instanceof Tool) {
			return null;
		}
		if (cc instanceof WorkProductType) {
			return null;
		}		
		return null;
	}
	
	private EReference getCategorizedRef(ContentCategory cc) {
		UmaPackage up = UmaPackage.eINSTANCE;
		if (cc instanceof CustomCategory) {
			return up.getCustomCategory_CategorizedElements();
		}
		if (cc instanceof Discipline) {
			return up.getDiscipline_Tasks();
		}
		if (cc instanceof DisciplineGrouping) {
			return null;
		}
		if (cc instanceof Domain) {
			return up.getDomain_WorkProducts();
		}
		if (cc instanceof RoleSet) {
			return up.getRoleSet_Roles();
		}
		if (cc instanceof RoleSetGrouping) {
			return null;
		}
		if (cc instanceof Tool) {
			return up.getTool_ToolMentors();
		}
		if (cc instanceof WorkProductType) {
			return up.getWorkProductType_WorkProducts();
		}		
		return null;
	}
	
}