//------------------------------------------------------------------------------
// 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.edit.uma.Scope;
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.VariabilityType;
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 (getConfiguration() instanceof Scope) {
			return 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)
					|| ConfigurationHelper.isExtendReplacer(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) {
		Set resultSet = null;
		List<DescribableElement> list = new ArrayList<DescribableElement>();
		for (Iterator<?> iter = result.iterator(); iter.hasNext();) {
			Object o = iter.next();
			if (o instanceof DescribableElement) {
				DescribableElement contElem0 = (DescribableElement) o;
				DescribableElement contElem = (DescribableElement) ConfigurationHelper
						.getCalculatedElement(contElem0, this);
				if (contElem != null) {
					if (seenSet.add(contElem)) {
						boolean toAdd = true;
						if (contElem0 instanceof VariabilityElement) {
							VariabilityElement ve = (VariabilityElement) contElem0;
							VariabilityElement base = ve.getVariabilityBasedOnElement();
							if (base != null && ve.getVariabilityType() == VariabilityType.CONTRIBUTES) {
								if (resultSet == null) {
									resultSet = new HashSet<Object>(result);
								}
								if (! resultSet.contains(contElem)) {
									toAdd = false;
								}									
							}
						}
						if (toAdd) {
							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;
	}
	
}
