//------------------------------------------------------------------------------
// Copyright (c) 2005, 2008 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.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.epf.library.IConfigurationManager;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.configuration.closure.ConfigurationClosure;
import org.eclipse.epf.library.configuration.closure.ElementReference;
import org.eclipse.epf.library.edit.util.DebugUtil;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.uma.ContentCategory;
import org.eclipse.epf.uma.Descriptor;
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.Role;
import org.eclipse.epf.uma.Task;
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.WorkProduct;
import org.eclipse.epf.uma.util.AssociationHelper;
import org.eclipse.epf.uma.util.UmaUtil;

/**
 *  Class managing supporting elements
 * 
 * @author Weiping Lu - Mar 22, 2008
 * @since 1.5
 */
public class SupportingElementData extends ConfigDataBase {
	
	private Set<MethodElement> supportingElements;
	private boolean duringUpdateSupporitngElements = false;
	private Set<MethodPlugin> supportingPlugins;
	private Set<MethodPackage> selectedPackages;
	private static boolean localDebug = false;
	private static boolean localDebug1 = false;
	private boolean enabled = true;
	
	//private Set<VariabilityElement> vChildrenContentCategorySet;
	private boolean localUpdate = false;
	
	public static boolean descriptorExclusiveOption = true;	
	
	public SupportingElementData(MethodConfiguration config) {
		super(config);
	}
	
	private boolean determineEnable() {
		supportingPlugins = new HashSet<MethodPlugin>();
		Set<MethodPlugin> plugins = new HashSet<MethodPlugin>(getConfig()
				.getMethodPluginSelection());
		for (MethodPlugin plugin : plugins) {
			if (plugin.isSupporting()) {
				supportingPlugins.add(plugin);
			}
		}
		
		setEnabled(supportingPlugins.size() < plugins.size());
		
		return isEnabled();
	}
	
	public void beginUpdateSupportingElements() {
		setUpdatingChanges(true);
		if (localDebug) {
			System.out.println("LD> beginUpdateSupportingElements -> "); //$NON-NLS-1$ 
		}
		
		supportingElements = new HashSet<MethodElement>();
		
		determineEnable();

		selectedPackages = new HashSet<MethodPackage>();
		
		if (isEnabled() && ! supportingPlugins.isEmpty()) {
			List<MethodPackage> packages = getConfig().getMethodPackageSelection();
			for (MethodPackage pkg : packages) {
				MethodPlugin plugin = UmaUtil.getMethodPlugin(pkg);
				if (supportingPlugins.contains(plugin)) {
					selectedPackages.add(pkg);
				}
			}
		}
		//vChildrenContentCategorySet = new HashSet<VariabilityElement>();

		if (localDebug) {
			System.out.println("LD> isEnabled(): " + isEnabled()); //$NON-NLS-1$
			System.out.println("LD> supportingPlugins: " + supportingPlugins.size()); //$NON-NLS-1$
			System.out.println("LD> selectedPackages: " + selectedPackages.size()); //$NON-NLS-1$ 
			System.out.println("LD> beginUpdateSupportingElements <- "); //$NON-NLS-1$ 
			System.out.println(""); //$NON-NLS-1$ 
		}		
	}
	
	// Collect map of referred references outside the config
	public void endUpdateSupportingElements(
			Map<String, ElementReference> outConfigRefMap) {
		if (localDebug) {
			System.out.println("LD> endUpdateSupportingElements -> "); //$NON-NLS-1$ 
		}
		if (isEnabled()) {
			Set<MethodElement> supportingElementsToCollect = new HashSet<MethodElement>(supportingElements);
			while (!supportingElementsToCollect.isEmpty()) {
				Set<MethodElement> newSupportingElements = new HashSet<MethodElement>();		
				processReferencesOutsideConfig(supportingElementsToCollect, outConfigRefMap, newSupportingElements);
				if (localDebug) {
					System.out.println("LD> newSupportingElements: " + newSupportingElements.size()); //$NON-NLS-1$
				}	
				supportingElementsToCollect = newSupportingElements;
			}
		}
		
		setUpdatingChanges(false);
		setNeedUpdateChanges(false);
		//vChildrenContentCategorySet = null;
		
		if (localDebug) {
			System.out.println("LD> supportingElements: " + supportingElements.size()); //$NON-NLS-1$
			System.out.println("LD> outConfigRefMap: " + outConfigRefMap.size()); //$NON-NLS-1$ 
			System.out.println("LD> endUpdateSupportingElements <- "); //$NON-NLS-1$ 
			System.out.println(""); //$NON-NLS-1$ 
		}	
	}
	
	private void processReferencesOutsideConfig(
			Collection<MethodElement> elements,
			Map<String, ElementReference> outConfigRefMap, Set<MethodElement> newSupportingElements) {
		for (MethodElement element : elements) {
			if (element instanceof ContentCategory) {
				continue;
			}
			processVariabilityChildren(element, newSupportingElements);
			processReferencesOutsideConfig(element, outConfigRefMap, newSupportingElements);
		}
	}
	
	private void processReferencesOutsideConfig(MethodElement element,
			Map<String, ElementReference> outConfigRefMap, Set<MethodElement> newSupportingElements) {
		IConfigurationManager configManager = LibraryService.getInstance().getConfigurationManager(
				getConfig());
		Set<VariabilityElement> replacerSet = null;
		if (configManager != null) {
			replacerSet = configManager.getDependencyManager().getReplacerSet();
		}		
		
		List properties = LibraryUtil.getStructuralFeatures(element);
		for (EStructuralFeature f: (List<EStructuralFeature>) properties) {			
			if (!(f instanceof EReference)) {
				continue;
			}

			EReference feature = (EReference) f;
			if (feature.isContainer() || feature.isContainment()) {
				continue;
			}
			
						
			if (element instanceof Task) {
				if (feature == UmaPackage.eINSTANCE.getTask_Steps()) {
					continue;
				}
			}
			
			if (element instanceof TaskDescriptor) {
				if (feature == UmaPackage.eINSTANCE.getTaskDescriptor_SelectedSteps()) {
					continue;
				}
			}
			
			if (feature == UmaPackage.eINSTANCE.getRole_Modifies()) {
				continue;
			}	

			Object value = element.eGet(feature);
			if (value == null) {
				continue;
			}
			
			List values = null;			
			if ( feature.isMany() ) {
				values = (List) value;
			} else if ( value instanceof MethodElement ) {
				if (descriptorExclusiveCheck((MethodElement) value, element, feature)) {
					continue;
				}				
				values = new ArrayList();
				values.add(value);
				
				if (replacerSet != null) {
					if (feature == UmaPackage.eINSTANCE.getVariabilityElement_VariabilityBasedOnElement()) {
						VariabilityElement ve = element instanceof VariabilityElement ?
								(VariabilityElement) element : null;
						VariabilityType type = ve == null ? null : ve.getVariabilityType();
						if (type == VariabilityType.EXTENDS_REPLACES ||
								type == VariabilityType.REPLACES) {
							replacerSet.add(ve);
						}
					}				
				}
				
			}
			
			String guid = element.getGuid();
			for (Object referredValue: values) {
				if (! (referredValue instanceof MethodElement)) {
					continue;
				}
				MethodElement referredElement = (MethodElement)	referredValue;
				boolean isOutConfig = checkOutConfigElement(referredElement, element, newSupportingElements);
				if (isOutConfig && outConfigRefMap != null){				
					String key = guid + referredElement.getGuid();
					ElementReference elementReference = outConfigRefMap.get(key);
					if (elementReference == null) {
						elementReference = new ElementReference(element, referredElement);
						outConfigRefMap.put(key, elementReference);
					}
					elementReference.addFeature(feature);
				}
			}
		}
		
	}
	
	private boolean descriptorExclusiveCheck(MethodElement referredElement, MethodElement referringElement, EStructuralFeature feature) {
		if (! descriptorExclusiveOption) {
			return false;
		}
		
		if (! (referringElement instanceof Descriptor)) {
			return false;
		}
		
		if (feature == UmaPackage.eINSTANCE.getTaskDescriptor_Task()) {
			return referredElement instanceof Task;
		}
		if (feature == UmaPackage.eINSTANCE.getRoleDescriptor_Role()) {
			return referredElement instanceof Role;		
		}
		if (feature == UmaPackage.eINSTANCE.getWorkProductDescriptor_WorkProduct()) {
			return referredElement instanceof WorkProduct;		
		}
		
		return false;
	}

	private boolean checkOutConfigElement(MethodElement referredElement, MethodElement referingElement, Set<MethodElement> newSupportingElements) {
		if (referredElement instanceof MethodPackage
				|| referredElement instanceof MethodConfiguration) {
			return false;
		}

		if (referredElement instanceof VariabilityElement) {
			VariabilityElement replacer = ConfigurationHelper.getReplacer(
					(VariabilityElement) referredElement, getConfig());
			if (replacer != null) {
				return false;
			}
		}

		// the element might be subtracted, so ignore it
		if (!supportingElements.contains(referingElement) && !ConfigurationHelper.inConfig(referingElement, getConfig(), true, false)) {
			return false;
		}

		if (!ConfigurationHelper.inConfig(referredElement, getConfig())
				&& !isOwnerSelected(referredElement, newSupportingElements)) {
			return true;
		}

		return false;
	}

	//ret: 0 = unknown, 1 = yes, 2 = no
	public int checkInConfigIndex(MethodElement element) {
		int ret = checkInConfigIndex_(element);
		if (localDebug1) {
			System.out.println("LD> isSE: " + ret +  //$NON-NLS-1$
					", element: " + DebugUtil.toString(element, 2));//$NON-NLS-1$ 
		}
		return ret;
	}
	
	//ret: 0 = unknown, 1 = yes, 2 = no
	private int checkInConfigIndex_(MethodElement element) {
		if (isUpdatingChanges()) {
			return 2;
			// throw new UnsupportedOperationException();
		} else if (isNeedUpdateChanges()) {
			if (bypassLogic()) {
				return 0;
			}
			updateChanges();
		}
		if (! isEnabled()) {
			return 0;
		}
		if (element instanceof ContentCategory) {
			return 1;
		}		
		return supportingElements.contains(element) ? 1 : 2;
	}
	
	protected void updateChangeImpl() {
		if (determineEnable()) {
			if (! bypassLogic()) {
				ConfigurationClosure closure = new ConfigurationClosure(null,
						getConfig());
				closure.dispose();
			}
		}
	}
	
	//isSupportingElement check during updating mode
	public boolean isSupportingElementCallDuringUpdating(ElementReference ref) {
		if (! isEnabled()) {
			return false;
		}
		MethodElement referringElement = ref.getElement();
		MethodElement referredElement = ref.getRefElement();
		EStructuralFeature feature = ref.getSingleFeature();
		if (descriptorExclusiveCheck(referredElement, referringElement, feature)) {
			return false;
		}
		return isOwnerSelected(referredElement, null);
	}
	
	private boolean isOwnerSelected(MethodElement element,
			Set<MethodElement> newSupportingElements) {
		return isOwnerSelected(element, newSupportingElements, true);
	}
		
	private boolean isOwnerSelected(MethodElement element,
				Set<MethodElement> newSupportingElements, boolean register) {
		if (! isUpdatingChanges()) {
			throw new UnsupportedOperationException();	
		}
		
		if (supportingElements.contains(element)) {
			return true;
		}

		boolean ret = false;
		EObject selectable = LibraryUtil.getSelectable(element);
		if (selectable instanceof MethodPackage) {
			ret = selectedPackages.contains(selectable);
		} else if (selectable instanceof MethodPlugin) {
			ret = supportingPlugins.contains(selectable);
		} else if (selectable instanceof MethodLibrary) {
			ret = true;
		}
		if (! register) {
			return ret;
		}
		if (ret) {
			registerAsSupporting(element, newSupportingElements);
		}
		return ret;
	}

	private void registerAsSupporting(MethodElement element,
			Set<MethodElement> newSupportingElements) {
		supportingElements.add(element);
		EObject pkg = element.eContainer();
		while (pkg != null && pkg instanceof MethodPackage) {
			supportingElements.add((MethodPackage) pkg);
			pkg = pkg.eContainer();
		}
		
		if (localDebug1) {
			System.out
					.println("LD> supportingElements added: " + DebugUtil.toString(element, 2));//$NON-NLS-1$ 
		}
		if (newSupportingElements != null) {
			newSupportingElements.add(element);
		}
	}
		
	public boolean isSupportingSelectable(MethodElement element) {
		if (! isEnabled()) {
			return false;
		}
		return selectedPackages.contains(element) || supportingPlugins.contains(element);
	}

	public boolean isEnabled() {
		return enabled;
	}

	public void setEnabled(boolean enabled) {
		this.enabled = enabled;
	}

	public static synchronized boolean isDescriptorExclusiveOption() {
		return descriptorExclusiveOption;
	}

	public static synchronized void setDescriptorExclusiveOption(
			boolean descriptorExclusiveOption) {
		if (SupportingElementData.descriptorExclusiveOption != descriptorExclusiveOption) {
			SupportingElementData.descriptorExclusiveOption = descriptorExclusiveOption;
			MethodLibrary lib = LibraryService.getInstance().getCurrentMethodLibrary();
			if (lib != null) {
				for (MethodConfiguration config : lib.getPredefinedConfigurations()) {
					IConfigurationManager mgr = LibraryService.getInstance().getConfigurationManager(config);
					if (mgr != null) {
						SupportingElementData sdata = mgr.getSupportingElementData();
						if (sdata != null) {
							sdata.setNeedUpdateChanges(true);
						}
					}
				}
			}
		
		}
	}
	
	public void processVariabilityChildren(MethodElement elementInConfig,
			Set<MethodElement> newSupportingElements) {
		if (!(elementInConfig instanceof VariabilityElement)) {
			return;
		}

		VariabilityElement base = (VariabilityElement) elementInConfig;
		List<VariabilityElement> vChildren = AssociationHelper
				.getImmediateVarieties(base);
		if (vChildren == null || vChildren.isEmpty()) {
			return;
		}
		
		boolean isContentCategory = base instanceof ContentCategory;
		
		for (VariabilityElement child : vChildren) {
			if (child.getVariabilityBasedOnElement() == base) { // double check
				if (child.getVariabilityType() == VariabilityType.CONTRIBUTES
						|| child.getVariabilityType() == VariabilityType.REPLACES
						|| child.getVariabilityType() == VariabilityType.EXTENDS_REPLACES) {
					// child may not be under an supporting plugin -> ok
					if (isOwnerSelected(child, null, false)) {
						List<VariabilityElement> replacers = getReplacers(child);
						if (replacers != null && !replacers.isEmpty()) {
							for (VariabilityElement replacer : replacers) {
								if (isOwnerSelected(replacer,
										newSupportingElements, true)
										&& isContentCategory) {
									//vChildrenContentCategorySet.add(child);
								}
							}
						} else {
							registerAsSupporting(child, newSupportingElements);
							if (isContentCategory) {
								//vChildrenContentCategorySet.add(child);
							}
						}
					} 

				}
			}
		}

	}
	
	private  List<VariabilityElement> getReplacers(VariabilityElement base) {
		MethodConfiguration config = getConfig();
		
		List<VariabilityElement> vChildren = AssociationHelper
		.getImmediateVarieties(base);
		
		if (vChildren == null || vChildren.isEmpty()) {
			return null;
		}
		
		List<VariabilityElement> replacers = new ArrayList<VariabilityElement>();
		for (VariabilityElement child : vChildren) {
			if (child.getVariabilityBasedOnElement() == base) { // double check
				if (child.getVariabilityType() == VariabilityType.REPLACES ||
					child.getVariabilityType() == VariabilityType.EXTENDS_REPLACES) {					
					if (ConfigurationHelper.inConfig(child, config)
							|| isOwnerSelected(child, null, false)) {
						replacers.add(child);
					}
				}
			}
		}
		return replacers;
	}
	
	public boolean bypassLogic() {
		boolean ret = bypassLogic_();
		//System.out.println("LD> bypassLogic: " + ret);
		return ret;
	}

	private boolean bypassLogic_() {
		if (! ConfigurationHelper.getDelegate().isAuthoringMode()) {
			return false;
		}
		
		if (ConfigurationHelper.getDelegate().isPublishingMode()) {
			return false;
		}
		
		if (! isUpdatingChanges()) {
			return true;
		}	
		
		return false;
	}	
	
}
