//------------------------------------------------------------------------------
// 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.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.epf.library.LibraryPlugin;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.PresentationContext;
import org.eclipse.epf.library.layout.BrowsingLayoutSettings;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.uma.CustomCategory;
import org.eclipse.epf.uma.DescribableElement;
import org.eclipse.epf.uma.FulfillableElement;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.RoleDescriptor;
import org.eclipse.epf.uma.TaskDescriptor;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.WorkProductDescriptor;
import org.eclipse.epf.uma.util.AssociationHelper;

/**
 * Realizes the element based on the configuration and realize options.
 * 
 * @author Jinhua Xi
 * @author Weiping Lu
 * @since 1.0
 */
public abstract class ElementRealizer {

	protected MethodConfiguration config;

	// note: discard contributor takes higher priority, if set to true,
	// resolveContributor will be ignored
	private boolean discardContributor = false;

	private boolean resolveContributor = true;

	private boolean resolveReplacer = true;

	private boolean showSubtracted = false;
	
	protected IFilter filter = null;
	
	// this is the default setting based on the preference setting
	// subclass should implement their own method the get the value
	private static boolean defaultEnableExtendReplace = false;
	
	
	//private static boolean defaultIgnoreBaseToManyAssociations = false;

	static {
		String str = LibraryPlugin.getDefault().getString("EnableExtendReplace"); //$NON-NLS-1$
		if ( str != null && str.trim().equals("true") ) { //$NON-NLS-1$
			defaultEnableExtendReplace = true;
		}
		
		// 171882 - Extends-Replace Variability
		//defaultIgnoreBaseToManyAssociations = LibraryPreferences.getUseNewExtendsSemantics();		
	}
	
	/**
	 * construct an instance with the give configuration
	 * @param config MethodConfiguration
	 */
	public ElementRealizer(MethodConfiguration config) {
		this(config, true, true);
	}

	/**
	 * construct an instance with the given configuration and additional realization options.
	 * 
	 * @param config MethodConfiguration
	 * @param resolveContributor boolean if true, contrubutors from feature value list will be resolved. default to false.
	 * @param resolveReplacer boolean if ture, element with a replacer will be resolved to the replacer. default to true.
	 */
	public ElementRealizer(MethodConfiguration config,
			boolean resolveContributor, boolean resolveReplacer) {
		this.config = config;
		this.resolveContributor = resolveContributor;
		this.resolveReplacer = resolveReplacer;
		
	}

	/**
	 * is extend-replace enabled for replacement
	 * 
	 * @return boolean
	 */
	public static boolean isExtendReplaceEnabled() {
		return defaultEnableExtendReplace;
	}
	
	/**
	 * get the global setting for the extend semantics
	 * @return
	 */
	public static boolean ignoreBaseToManyAssociations() {
		return BrowsingLayoutSettings.INSTANCE.isUseNewExtendSemantics();
	}
	
	
	/**
	 * set the flag. if true, the contributors from a realized feature list will be discarded
	 * 
	 * @param discardContributor boolean
	 */
	public void setDiscardContributor(boolean discardContributor) {
		this.discardContributor = discardContributor;
	}

	/**
	 * set the flag. if true the contributors will be resolved.
	 * @param resolveContributor boolean
	 */
	public void setResolveContributor(boolean resolveContributor) {
		this.resolveContributor = resolveContributor;
	}

	/**
	 * set the flag. if true the element with a replacer will be resolved to the replacer.
	 * 
	 * @param resolveReplacer boolean
	 */
	public void setResolveReplacer(boolean resolveReplacer) {
		this.resolveReplacer = resolveReplacer;
	}

	public boolean showSubtracted() {
		return showSubtracted;
	}
	
	public void setShowSubtracted(boolean flag) {
		this.showSubtracted = flag;
	}
	

	/**
	 * set a filter for this realizer
	 * @param filter IFilter
	 */
	public void setFilter(IFilter filter) {
		this.filter = filter;
	}
	
	/**
	 * get tyhe configuration
	 * @return
	 */
	public MethodConfiguration getConfiguration() {
		return config;
	}
	
	/**
	 * realize the element
	 * @param element MethodElement
	 * @return MethodElement
	 */
	public MethodElement realize(MethodElement element) {
		
		if (element == null || !inConfig(element)) {
			return null;
		}

		// Work product descriptors that point to work products
		// outside the configuration are still published
		// linked element must be in config as well
		MethodElement linkedElement = null;
		if (element instanceof TaskDescriptor) {
			linkedElement = ((TaskDescriptor) element).getTask();
		} else if (element instanceof WorkProductDescriptor) {
			linkedElement = ((WorkProductDescriptor) element).getWorkProduct();
		} else if (element instanceof RoleDescriptor) {
			linkedElement = ((RoleDescriptor) element).getRole();
		}

		if ((linkedElement != null)
				&& !inConfig(linkedElement)) {
			return null;
		}

		// if no configuration is specified, don't calculate
		if (config == null) {
			return element;
		}

		if (element instanceof VariabilityElement) {
			VariabilityElement ve = (VariabilityElement) element;
			VariabilityElement e;

			// if discardContributor set to true, discard the contributor and
			// return null
			if (discardContributor && ConfigurationHelper.isContributor(ve)) {
				return null;
			}

			if (resolveContributor) {
				// if the element is a contributor, resovle to it's base
				while (ConfigurationHelper.isContributor(ve)) {
					e = ve.getVariabilityBasedOnElement();
					if (inConfig(e)) {
						ve = e;
					} else {
						// if the base is not in the configuration, it's an
						// error
						System.out
								.println("Configuration closure error: Base element '" + LibraryUtil.getTypeName(ve) + "' not in configuration"); //$NON-NLS-1$ //$NON-NLS-2$
						break;
					}
				}
			}

			if (resolveReplacer) {
				e = ConfigurationHelper.getReplacer(ve, config);
				if (e != null) {
					return e;
				}
			} else if (!inConfig(ve)) {
				return null;
			}
			
			// if the element is a replacer, and the base is a contributor, 
			// need to resolve the element to the base if resolveContributor is true
			// 152230 - Browsing: Role<-->WP relationship shows inconsistancy
			e = ve;
			while ((e != null) && ConfigurationHelper.isReplacer(e)) {
				e = (VariabilityElement) e.getVariabilityBasedOnElement();
				if (ConfigurationHelper.isContributor(e)) {
					return realize(e);
				}
			}
			
			// can't return here, need to check canShow
			// return ve;
			if (canShow(ve)) {
				return ve;
			}

			return null;
		}

		if (canShow(element)) {
			return element;
		}

		return null;
	}

	/**
	 * realize the list of feature values and returns a new list of values
	 * The new might be a re-sorting of the original list 
	 * or some of the values can be filtered out, depending on the detail implementation
	 * Note: the list value passed in might be updated as well.
	 * @param element MethodElement
	 * @param feature EStructuralFeature
	 * @param values List
	 * @return List
	 */
	public abstract List realize(MethodElement element,
			EStructuralFeature feature, List values);
	
	/**
	 * 
	 * @param element
	 * @return boolean
	 */
	public boolean inConfig(MethodElement element) {
		return ConfigurationHelper.inConfig(element, config, !showSubtracted());
	}
	
	/**
	 * 
	 * @param element
	 * @return boolean
	 */
	public boolean canShow(MethodElement element) {
		return ConfigurationHelper.canShow(element, config, !showSubtracted());
	}
	
	public void dispose() {
		this.filter = null;
	}
	
	protected void addExtraFeatureValues(MethodElement element, EStructuralFeature feature,
			FeatureValue values) {
		if (!ElementRealizer.toAddExtraFeatureValues(element, feature, values,
				getConfiguration())) {
			return;
		}
		
		CustomCategory cc = (CustomCategory) element;

		Collection<?> result = LibraryUtil.getIncludedElements(cc, getConfiguration());

		if (result == null || result.isEmpty()) {
			return;
		}

		ToManyFeatureValue manyValues = values instanceof ToManyFeatureValue ?
				(ToManyFeatureValue) values : null;
				
		List oldValues = manyValues == null ? null : (List) manyValues.getValue();

		HashSet<DescribableElement> seenSet = manyValues == null ?
				new HashSet<DescribableElement>() : new HashSet<DescribableElement>(oldValues);	
		seenSet.add(cc);
		List ccList = AssociationHelper.getCustomCategories(cc);
		seenSet.addAll(ccList);					
				
		List<DescribableElement> list = calculateList(result, seenSet);
		values.add(cc, list);
		
	}

	public List<DescribableElement> calculateList(Collection<?> result,
			Set<DescribableElement> seenSet) {
		List<DescribableElement> list = new ArrayList<DescribableElement>();
		for (Iterator<?> iter = result.iterator(); iter.hasNext();) {
			Object o = iter.next();
			if (o instanceof DescribableElement) {
				DescribableElement contElem = (DescribableElement) o;
				contElem = (DescribableElement) ConfigurationHelper
						.getCalculatedElement(contElem, this);
				if (contElem != null) {
					if (seenSet.add(contElem)) {
						list.add(contElem);
					}
				}
			}
		}
		
		if (list.size() > 1) {
			Comparator comparator = PresentationContext.INSTANCE.getPresNameComparator();
			Collections.<DescribableElement>sort(list, comparator);
		}
		
		return list;
	}
	
	protected boolean slotMatching(FulfillableElement slot, FulfillableElement element) {		
		return true;
	}

	protected static boolean toAddExtraFeatureValues(MethodElement element,
			EStructuralFeature feature, FeatureValue values,
			MethodConfiguration config) {
		if (config == null) {
			return false;
		}

		if (!(values instanceof ToManyFeatureValue)) {
			return false;
		}

		if (!(element instanceof CustomCategory)) {
			return false;
		}

		if (feature != UmaPackage.eINSTANCE
				.getCustomCategory_CategorizedElements()) {
			return false;
		}

		return true;
	}
	
}
