//------------------------------------------------------------------------------
// 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.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.epf.library.IConfigurationClosure;
import org.eclipse.epf.library.IConfigurationManager;
import org.eclipse.epf.library.LibraryPlugin;
import org.eclipse.epf.library.LibraryResources;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.services.DependencyManager;
import org.eclipse.epf.library.services.ElementDependency;
import org.eclipse.epf.library.services.ElementReference;
import org.eclipse.epf.library.services.PackageReference;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
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.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertySource;

/**
 * A method configuration closure.
 * 
 * @author Jinhua Xi
 * @author Kelvin Low
 * @since 1.0
 */
public class ConfigurationClosure implements IConfigurationClosure {

	// If true, generate debug traces.
	protected static boolean debug = LibraryPlugin.getDefault().isDebugging();

	protected MethodConfiguration config = null;

	protected MethodLibrary library = null;

	protected IConfigurationManager configManager = null;

	protected DependencyManager dependencyManager = null;

	// Node change information. The object are the model objects
	// check the linked objects in needed
	protected List selected = new ArrayList();

	// A map of invalid nodes to ElementDependencyError objects.
	protected Map invalidNodesMap = new HashMap();

	protected List changedNodes = new ArrayList();

	/**
	 * Creates a new instance.
	 * 
	 * @param config
	 *            A method configuration.
	 */
	public ConfigurationClosure(MethodConfiguration config) {
		this.config = config;

		configManager = LibraryService.getInstance().getConfigurationManager(
				config);
		if (configManager != null) {
			library = configManager.getMethodLibrary();
			dependencyManager = configManager.getDependencyManager();
		}

		// cleanup the old status and rebuild the list
		selected.clear();
		changedNodes.clear();
		invalidNodesMap.clear();

		// configuration changed, re-build the selection list
		try {
			buildList(library);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * Returns the method configuration manager.
	 * 
	 * @return A <code>ConfigurationManager</code>.
	 */
	public IConfigurationManager getConfigurationManager() {
		return configManager;
	}

	/**
	 * Returns the method configuration.
	 * 
	 * @return A <code>MethodConfiguration</code>.
	 */
	public MethodConfiguration getConfiguration() {
		return config;
	}

	/**
	 * Returns the containining method library.
	 * 
	 * @return A <code>MethodConfiguration</code>.
	 */
	public MethodLibrary getLibrary() {
		return library;
	}

	/**
	 * Builds the selection list based on the method configuration.
	 * 
	 * @param input
	 */
	private void buildList(EObject input) {
		// Validate the method configuration.
		LibraryUtil.validateMethodConfiguration(config);

		selected.addAll(config.getMethodPluginSelection());
		selected.addAll(config.getMethodPackageSelection());

		// Re-build the selections to auto add the process packages.
		setSelections(selected.toArray());
	}

	/**
	 * Sets the method plug-ins and packages selection.
	 * 
	 * @param elements
	 *            An array of method plug-ins and packages.
	 */
	public void setSelections(Object[] elements) {
		if (elements == null) {
			return;
		}

		// Cleanup the old status and rebuild the list.
		selected.clear();
		changedNodes.clear();
		invalidNodesMap.clear();
		beginUpdate();

		for (int i = 0; i < elements.length; i++) {
			Object e = elements[i];
			if (!selected.contains(e)) {
				if ((e instanceof EObject)) {
					add((EObject) e, false);

					// If the selected element is a process component,
					// select all the process packages that contains the
					// activities.
					if (e instanceof ProcessComponent) {
						selectProcessPackages(((ProcessComponent) e)
								.getProcess());
					}
				} else {
					// The selected element is a UI folder.
					selected.add(e);
				}
			}
		}

		endUpdate();
	}

	private void selectProcessPackages(Activity a) {
		if (a == null) {
			return;
		}

		for (Iterator it = a.getBreakdownElements().iterator(); it.hasNext();) {
			BreakdownElement e = (BreakdownElement) it.next();
			Object pkg = e.eContainer();
			if (!selected.contains(pkg)) {
				selected.add(pkg);
				changedNodes.add(pkg);
			}

			if (e instanceof Activity) {
				selectProcessPackages((Activity) e);
			}
		}
	}

	/**
	 * Adds a method plug-in or package to the closure.
	 * 
	 * @param element
	 *            A method element.
	 * @param addChildren
	 *            if <code>true</code>, add all child method elements.
	 */
	private void add(EObject element, boolean addChildren) {
		if (!LibraryUtil.selectable(element)) {
			return;
		}

		if (!selected.contains(element)) {
			selected.add(element);

			// Save the changed nodes so that we can update the status later.
			addChanged(element);

			if (element instanceof MethodPlugin) {
				selectSystemPackages((MethodPlugin) element);
			}
		}

		// Add the parent method element as well.
		EObject parent = element.eContainer();
		if ((parent != null) && !selected.contains(parent)) {
			add(parent, false);
		}

		// Add children as needed.
		if (addChildren) {
			EList elements = element.eContents();
			if (elements != null) {
				for (Iterator it = elements.iterator(); it.hasNext();) {
					EObject child = (EObject) it.next();
					add(child, true);
				}
			}
		}
	}

	private void addChanged(Object element) {
		if (!changedNodes.contains(element)) {
			changedNodes.add(element);
		}
	}

	private void selectSystemPackages(MethodPlugin plugin) {
		List pkgs = TngUtil.getAllSystemPackages(plugin);
		for (Iterator it = pkgs.iterator(); it.hasNext();) {
			EObject pkg = (EObject) it.next();
			add(pkg, false);
		}
	}

	/**
	 * Checks whether a method plug-in or package is selected.
	 * 
	 * @return <code>true</code> if the given element is selected.
	 */
	public boolean isSelected(Object input) {
		if ((input instanceof MethodLibrary) || input == config
				|| selected.contains(input)) {
			return true;
		}
		return false;
	}

	/**
	 * Gets the element dependency error for a method element.
	 * 
	 * @element A method element.
	 * 
	 * @return An <code>ElementDependencyError</code>.
	 */
	public ElementDependencyError getError(Object element) {
		return getError(element, false);
	}

	private ElementDependencyError getError(Object element, boolean create) {
		ElementDependencyError error = (ElementDependencyError) invalidNodesMap
				.get(element);
		if (error == null && create) {
			error = new ElementDependencyError(element);
			invalidNodesMap.put(element, error);
		}
		return error;
	}

	/**
	 * check if there is error in this configuration closure
	 * 
	 * @return boolean
	 */
	public boolean hasError() {
		for (Iterator it = invalidNodesMap.values().iterator(); it.hasNext();) {
			ElementDependencyError error = (ElementDependencyError) it.next();
			if (error.isError()) {
				return true;
			}
		}
		return false;
	}

	/**
	 * check if there is any problem (error/warning) with this configuration closure.
	 * @return boolean
	 */
	public boolean hasProblem() {
		return invalidNodesMap.size() > 0;
	}

	/**
	 * Returns all the errors.
	 * 
	 * @return A a list of <code>ErrorInfo</code>.
	 */
	public List getAllErrors() {
		List errors = new ArrayList();
		for (Iterator it = invalidNodesMap.values().iterator(); it.hasNext();) {
			ElementDependencyError error = (ElementDependencyError) it.next();
			errors.addAll(error.getAll());
		}
		return errors;
	}

	/**
	 * Returns all the dependency errors.
	 * 
	 * @return An array of <code>ElementDependencyError</code>
	 */
	public Object[] getDependencyErrors() {
		return invalidNodesMap.values().toArray();
	}

	/**
	 * Returns all the invalid elements.
	 * 
	 * @return A list of invalid elements.
	 */
	public List getInvalidElements() {
		return new ArrayList(invalidNodesMap.keySet());
	}

	private void removeError(Object element) {
		if (invalidNodesMap.containsKey(element)) {
			invalidNodesMap.remove(element);

			// Error status changed, add it to the changed list.
			if (!changedNodes.contains(element)) {
				changedNodes.add(element);
			}
		}
	}

	/**
	 * Returns all the changed elements. These are elements whose check states
	 * have changed or whose image have changed due to error.
	 * 
	 * @return A list of changed method elements.
	 */
	public List getChangedElements() {
		List items = new ArrayList(changedNodes);
		for (Iterator it = invalidNodesMap.keySet().iterator(); it.hasNext();) {
			Object item = it.next();
			if (!items.contains(item)) {
				items.add(item);
			}
		}
		return items;
	}

	/**
	 * Returns the method plug-ins and packages selection.
	 * 
	 * @return An array of method plug-ins and packages.
	 */
	public Object[] getSelection() {
		return selected.toArray();
	}

	/**
	 * begin the closure update.
	 *
	 */
	public void beginUpdate() {
		changedNodes.clear();
	}

	/**
	 * end the closure update.
	 *
	 */
	public void endUpdate() {
		// Process the changed elements.
		// Note: additional elements may be added to the changesNodes due to
		// error status change but only the original changed elements need to be
		// processed.
		for (Iterator it = new ArrayList(changedNodes).iterator(); it.hasNext();) {
			Object changedElement = it.next();
			ElementDependency dependency = dependencyManager
					.getDependency((MethodElement) changedElement);
			if (dependency == null) {
				continue;
			}

			if (isSelected(changedElement)) {
				validateSelected(dependency);
			} else {
				validateUnSelected(dependency);
			}
		}

		if (debug) {
			System.out
					.println("There are (" + invalidNodesMap.size() + ") errors"); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	/**
	 * Validates the element dependency when the element is selected. When the
	 * element is selected, we need to do the following: 1. Check error for
	 * references 2. Remove error for dependents associated with element 3.
	 * Update parents: if the selection is valid, remove all errors from parents
	 * associated with this element if the selection is invalid, set error to
	 * all parents.
	 * 
	 * @param dependency
	 *            ElementDependency
	 */
	private void validateSelected(ElementDependency dependency) {
		Object changedElement = dependency.getElement();

		// Since this element is selected, remove all previous errors.
		removeError(changedElement);

		if (changedElement instanceof MethodLibrary) {
			return;
		}

		// Since this element is selected, remove all dependency errors in the
		// dependent elements.
		List dependents = dependency.getDependents();
		if (dependents != null && dependents.size() > 0) {
			Object element;
			for (Iterator itr = dependents.iterator(); itr.hasNext();) {
				element = itr.next();

				ElementDependencyError error = getError(element, false);
				if (error != null) {
					error.removeError(changedElement);
					if (error.size() == 0) {
						removeError(element);

						// Clear the parent error introduced by this element.
						updateParentsForErrors((EObject) element);

					}
				}
			}
		}

		// If an element is checked, check the element it depends on,
		// which should be checked as well.
		List refs = dependency.getReferences();
		if (refs != null && refs.size() > 0) {
			PackageReference ref;
			Object element;
			for (Iterator itr = refs.iterator(); itr.hasNext();) {
				ref = (PackageReference) itr.next();
				element = ref.getRefElement();

				if (element instanceof MethodLibrary) {
					continue;
				}

				// Don't warn on optional inputs not being
				// present, so added the canIgnore() method
				if (!isSelected(element) && !canIgnore(ref)) {
					String message;
					int errorType = 0;
					if (ref.hasBaseReference()) {
						errorType = ErrorInfo.ERROR;
						message = LibraryResources.configClosureWarning_msg2;
					} else {
						errorType = ErrorInfo.WARNING;
						message = LibraryResources.configClosureWarning_msg3;
					}

					ElementDependencyError error = getError(changedElement,
							true);
					error.addError(new ErrorInfo(errorType, message,
							changedElement, element, ErrorInfo.REFERENCE_TO));
				} else {
					ElementDependencyError error = getError(changedElement,
							false);
					if (error != null) {
						error.removeError(element);
					}
				}
			}
		}

		// Finally, update the parents.
		updateParentsForErrors((EObject) changedElement);
	}

	/**
	 * Validates the ElementDependency when the element is unselected. When the
	 * element is unselected, we need to do the following: 1. check error for
	 * dependencts 2. remove error for references associated with element, in
	 * case of any added when the element was check 3. update parents: if the
	 * selection is valid, remove all errors from parents associated with this
	 * element if the selection is invalid, set error to all parents.
	 * 
	 * @param dependency
	 *            A <code>ElementDependency</code> object.
	 */
	private void validateUnSelected(ElementDependency dependency) {
		Object changedElement = dependency.getElement();

		// Since this element is un-selected, remove all previous errors.
		removeError(changedElement);

		if (changedElement instanceof MethodLibrary) {
			return;
		}

		// Since this element is un-selected, remove all errors in the
		// referenced elements.
		List refs = dependency.getReferences();
		if (refs != null && refs.size() > 0) {
			ElementReference ref;
			Object element;
			for (Iterator itr = refs.iterator(); itr.hasNext();) {
				ref = (ElementReference) itr.next();
				element = ref.getRefElement();

				ElementDependencyError error = getError(element, false);
				if (error != null) {
					error.removeError(changedElement);
					if (error.size() == 0) {
						removeError(element);

						// Clear the parent error introduced by this element.
						updateParentsForErrors((EObject) element);

					}
				}
			}
		}

		// If an element is unchecked, check the dependent elements.
		// If there are check elements depending on it, the element can't be
		// unchecked.
		List dependents = dependency.getDependents();
		if (dependents != null && dependents.size() > 0) {
			Object element;
			for (Iterator itr = dependents.iterator(); itr.hasNext();) {
				element = itr.next();

				if (element instanceof MethodLibrary) {
					continue;
				}

				if (isSelected(element)) {
					// Determine the type of dependency.
					ElementDependency childDep = dependencyManager
							.getDependency((MethodElement) element);

					validateSelected(childDep);
				} else {
					removeError(changedElement);
				}
			}
		}

		// finally, update the parents
		updateParentsForErrors((EObject) changedElement);
	}

	private void updateParentError(EObject parent, EObject element,
			int errorType) {
		if (parent == null || (parent instanceof MethodLibrary)) {
			return;
		}

		if ((parent instanceof MethodPackage)
				&& ConfigurationHelper.isGlobalPackage((MethodPackage) parent)) {
			updateParentError(parent.eContainer(), element, errorType);
			return;
		}

		// Remove the error associated with this element from all parents.
		ElementDependencyError error = getError(parent, false);
		if (error != null && error.size() > 0) {
			error.removeError(element);
		}

		if (errorType != ErrorInfo.NONE) {
			// Propegate the error to all parents.
			error = getError(parent, true);
			String message = LibraryResources.configClosureWarning_msg1;
			error.addError(new ErrorInfo(errorType, message, parent, element,
					ErrorInfo.NONE));
		} else if ((error != null) && (error.size() == 0)) {
			removeError(parent);
		}

		updateParentError(parent.eContainer(), element, errorType);
	}

	private void updateParentsForErrors(EObject element) {
		int errorType = ErrorInfo.NONE;

		ElementDependencyError error = getError(element);
		if (error != null && error.size() > 0) {
			if (error.isError() || error.isChildError()) {
				errorType = ErrorInfo.CHILD_ERROR;
			} else if (error.isWarning() || error.isChildWarning()) {
				errorType = ErrorInfo.CHILD_WARNING;
			}
		}

		updateParentError(element.eContainer(), element, errorType);
	}

	/**
	 * accept the cutrrent selection and ignore any warning message. make the
	 * configuration.
	 * 
	 */
	public void makeClosure() {
		// If no error. update the method configuration.
		while (hasError()) {
			fixProblems(true);
		}
	}

	/**
	 * fix all error(s) and warnign(s)
	 * 
	 */
	public void fixProblems() {
		// If no error, update the method configuration.
		while (hasProblem()) {
			fixProblems(false);
		}
	}

	private void fixProblems(boolean errorOnly) {
		// Note: make closure will select elements as needed.
		// so we need to make a copy of the current selcted ones
		// in order to trace the status
		List currentSelected = new ArrayList(selected);

		// beginUpdate();

		// list of errorInfo objects
		List errors = getAllErrors();
		if (errors.size() > 0) {
			invalidNodesMap.clear();
			ErrorInfo error;
			EObject ownerElement, causeElement;
			boolean ownerSelected, causeSelected;
			for (Iterator it = errors.iterator(); it.hasNext();) {
				error = (ErrorInfo) it.next();

				ownerElement = (EObject) error.getOwnerElement();
				causeElement = (EObject) error.getCauseElement();
				addChanged(ownerElement);
				addChanged(causeElement);
				if (error.isChildError() || error.isChildWarning()) {
					continue;
				}

				if (error.isWarning() && errorOnly) {
					continue;
				}

				ownerSelected = currentSelected.contains(ownerElement);
				causeSelected = currentSelected.contains(causeElement);

				// If the owner element is not selected
				// the error is caused by un-selecting this element,
				// select it will fix the error

				// If the owner element is selected, the error is caused by
				// un-selected references.
				// select those cause elements will fix the error
				if (!ownerSelected) {
					selectErrorElement(ownerElement);
				} else if (!causeSelected) {
					selectErrorElement(causeElement);
				}
			}
		}

		endUpdate();
	}

	private void selectErrorElement(EObject element) {
		// The selection is based on a package level. When a non-package element
		// is selected, all it's non-package siblings must be selected as well.
		if (LibraryUtil.selectable(element)) {
			add(element, true);
		}
	}

	/**
	 * update the method configuration in the library with the current selections
	 */
	public void saveMethodConfiguration() {
		List plugins = config.getMethodPluginSelection();
		List packages = config.getMethodPackageSelection();

		plugins.clear();
		packages.clear();

		EObject element;
		for (Iterator it = selected.iterator(); it.hasNext();) {
			element = (EObject) it.next();
			if (element instanceof MethodPlugin) {
				if (!plugins.contains(element)) {
					plugins.add(element);
				}
			} else if ((element instanceof MethodPackage)
					&& !ConfigurationHelper
							.isGlobalPackage((MethodPackage) element)) {
				if (!packages.contains(element)) {
					packages.add(element);
				}
			}
		}
	}

	/**
	 * Packages the library based on the selection.
	 * <p>
	 * Note: This will change the current library. Before calling this method, a
	 * copy of the current library should be created with the following steps:
	 * 1. Create a new <code>ConfigurationManager</code> with a copy of the
	 * original library, 2. Rebuild the dependency, 3. Create a
	 * <code>ConfigurationClosure</code> with the current configuration.
	 * 
	 * @return A <code>MethodLibrary</code>.
	 */
	public MethodLibrary packageLibrary(boolean removeBrokenReferences) {
		processSelection(library, removeBrokenReferences);

		// Remove the configurations except for the current one.
		List configs = library.getPredefinedConfigurations();
		configs.clear();
		configs.add(config);

		return library;
	}

	/**
	 * process the selected package by removeing all unselected elements and any
	 * missing references
	 * 
	 * @param element
	 */
	private void processSelection(EObject element,
			boolean removeBrokenReferences) {
		if (removeBrokenReferences) {
			// Iterator the references and remove broken references.
			EList references = element.eCrossReferences();
			if (references != null) {
				for (Iterator it = new ArrayList(references).iterator(); it
						.hasNext();) {
					EObject ref = (EObject) it.next();
					EObject pkgRef = LibraryUtil.getSelectable(ref);
					if (pkgRef != null && !isSelected(pkgRef)) {
						removeReference(element, ref);
					}
				}
			}
		}

		EList elements = element.eContents();
		if (elements != null) {
			for (Iterator it = new ArrayList(elements).iterator(); it.hasNext();) {
				EObject child = (EObject) it.next();

				// If the child element is selectable but it is not in the
				// configuration, remove it.
				if (LibraryUtil.selectable(child) && !isSelected(child)) {
					EcoreUtil.remove(child);
				} else {
					processSelection(child, removeBrokenReferences);
				}
			}
		}
	}

	private void removeReference(EObject ownerElement, EObject refElement) {
		AdapterFactoryContentProvider provider = configManager
				.getContentProvider();
		IPropertySource ps = provider.getPropertySource(ownerElement);
		IPropertyDescriptor[] pds = ps.getPropertyDescriptors();
		if (pds != null && pds.length > 0) {
			for (int i = 0; i < pds.length; i++) {
				IPropertyDescriptor descriptor = (IPropertyDescriptor) pds[i];
				Object id = descriptor.getId();
				Object value = ps.getPropertyValue(id);

				// Check whether the value needs to be converted to an editable
				// value.
				IPropertySource source = provider.getPropertySource(value);
				if (source != null) {
					value = source.getEditableValue();
				}
				if (value instanceof EList) {
					EList refList = (EList) value;
					if (refList.contains(refElement)) {
						if (debug) {
							System.out
									.println("Reference [" + LibraryUtil.getName(refElement) //$NON-NLS-1$
											+ "] removed from [" //$NON-NLS-1$
											+ LibraryUtil.getName(ownerElement)
											+ "]'s reference list"); //$NON-NLS-1$
						}
						refList.remove(refElement);
						ps.setPropertyValue(id, refList);
					}
				} else if (value instanceof MethodElement) {
					if (debug) {
						System.out
								.println("Reference [" + LibraryUtil.getName(refElement) //$NON-NLS-1$
										+ "] removed from [" //$NON-NLS-1$
										+ LibraryUtil.getName(ownerElement)
										+ "]"); //$NON-NLS-1$
					}
					ps.setPropertyValue(id, null);
				}

			}
		}
	}

	/**
	 * Disposes resources allocated by this closure.
	 */
	public void dispose() {
		configManager = null;
		config = null;
		library = null;
		dependencyManager = null;
		selected.clear();
		changedNodes.clear();
		invalidNodesMap.clear();
	}

	private boolean canIgnore(PackageReference pkgRef) {
		return pkgRef.canIgnore();
	}

}
