//------------------------------------------------------------------------------
// 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.edit.validation;

import java.util.Collection;
import java.util.Iterator;

import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.edit.provider.AdapterFactoryTreeIterator;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.LibraryEditResources;
import org.eclipse.epf.library.edit.process.BSActivityItemProvider;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.Suppression;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.CapabilityPattern;
import org.eclipse.epf.uma.DescribableElement;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.NamedElement;
import org.eclipse.epf.uma.Role;
import org.eclipse.epf.uma.RoleDescriptor;
import org.eclipse.epf.uma.TaskDescriptor;
import org.eclipse.epf.uma.TeamProfile;
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.osgi.util.NLS;

/**
 * This class defines various static methods to validate name of specified
 * object
 * 
 * @author Phong Nguyen Le
 * @since 1.0
 */
public final class NameChecker {

	private static final String ELEMENT_TEXT = LibraryEditResources.element_text; 
	
	private static final INameProvider presentationNameProvider = new INameProvider() {

		public String getName(Object object) {
			if(object instanceof BreakdownElement) {
				return ProcessUtil.getPresentationName((BreakdownElement) object);
			}
			else if(object instanceof DescribableElement) {
				return ((DescribableElement)object).getPresentationName();
			}
			return null;
		}
		
	};
	
	private static String checkName(AdapterFactory adapterFactory,
			Object parent, Object e, final Class type,
			INameProvider nameProvider, String newName, Suppression suppresion,
			boolean ignoreSuppressed) {
		IFilter childFilter = new IFilter() {

			public boolean accept(Object obj) {
				return type.isInstance(obj);
			}

		};

		return checkName(adapterFactory, parent, e, childFilter, nameProvider,
				newName, suppresion, ignoreSuppressed);
	}

	private static String checkName(AdapterFactory adapterFactory,
			Object parent, Object e, IFilter childFilter,
			EStructuralFeature nameFeature, String newName,
			Suppression suppression, boolean ignoreSuppressed) {
		return checkName(adapterFactory, parent, e, childFilter,
				createNameProvider(nameFeature), newName, suppression,
				ignoreSuppressed);
	}

	private static String checkName(AdapterFactory adapterFactory,
			Object parent, Object e, IFilter childFilter,
			INameProvider nameProvider, String newName,
			Suppression suppression, boolean ignoreSuppressed) 
	{
		if (ignoreSuppressed)
			if (suppression != null && suppression.isSuppressed(e)) {
				return null;
			}

		ITreeItemContentProvider adapter = (ITreeItemContentProvider) adapterFactory
				.adapt(parent, ITreeItemContentProvider.class);
		Collection children;

		// get children of the rolled-down dapter
		//
		boolean wasRolledUp = false;
		BSActivityItemProvider bsItemProvider = null;
		if (adapter instanceof BSActivityItemProvider) {
			bsItemProvider = ((BSActivityItemProvider) adapter);
			wasRolledUp = bsItemProvider.isRolledUp();
		}
		try {
			if (wasRolledUp) {
				bsItemProvider.setRolledUp(false);
			}
			children = adapter.getChildren(parent);
		} catch (NullPointerException ex) {
			throw ex;
		} finally {
			if (wasRolledUp) {
				bsItemProvider.basicSetRolledUp(wasRolledUp);
			}
		}
		
		if (e instanceof BreakdownElement) {
			return null;
		}

		for (Iterator iter = children.iterator(); iter.hasNext();) {
			Object item = iter.next();

			// skip checking on suppressed element
			//
/*170058	if (suppression != null && suppression.isSuppressed(item)) {
				continue;
			}*/

			Object child = TngUtil.unwrap(item);
			if (child != e && childFilter.accept(child)) {
				String name = nameProvider.getName(child);
				if (name.equalsIgnoreCase(newName)) {
					// return I18nUtil.formatString(RESOURCE_BUNDLE, key, data);
					return NLS.bind(
							LibraryEditResources.duplicateElementNameError_msg,
							name);
				}
			}
		}
		return null;
	}

	private static INameProvider createNameProvider(
			final EStructuralFeature nameFeature) {
		if(nameFeature == UmaPackage.eINSTANCE
								.getDescribableElement_PresentationName()) {
			return presentationNameProvider; 
		}
		
		return new INameProvider() {

			public String getName(Object object) {
				if (object instanceof EObject) {
					return (String) ((EObject) object).eGet(nameFeature);
				} else {
					return null;
				}
			}

		};
	}

	public static String checkName(AdapterFactory adapterFactory,
			final BreakdownElement e, Class type, EStructuralFeature nameFeature,
			String newName, Suppression suppression) 
	{
		return checkName(adapterFactory, null, e, type, nameFeature, newName,
				suppression, false);
	}
	
	public static String checkName(AdapterFactory adapterFactory, Object parent,
			final BreakdownElement e, Class type, final EStructuralFeature nameFeature,
			String newName, Suppression suppression, boolean ignoreSuppressed) 
	{
		String msg = checkEmpty(e, newName);
		if(msg != null) {
			return msg;
		}

		if(type == null) {
			type = chooseType(e);
		}
		
		if(parent == null) {
			ITreeItemContentProvider itemProvider = (ITreeItemContentProvider) adapterFactory
					.adapt(e, ITreeItemContentProvider.class);
			parent = itemProvider.getParent(e);
			if(parent == null) {
				return null;
			}
		}

		// basic check
		//
		msg = checkName(adapterFactory, parent, e, type,
				createNameProvider(nameFeature), newName, suppression,
				ignoreSuppressed);

		if (msg != null)
			return msg;
		IFilter childFilter = null;
		if (e instanceof TeamProfile) {
			// don't allow team with the same name within the same scope
			//
			childFilter = new IFilter() {
				public boolean accept(Object obj) {
					return e instanceof TeamProfile;
				}
			};
		}

		// PLEASE DON'T CLEAN UP.
		// Commented out for now, since we change scope of Deliverable.
		// else if (e instanceof WorkProductDescriptor
		// && ((WorkProductDescriptor) e).getWorkProduct() instanceof
		// Deliverable) {
		// childFilter = new IFilter() {
		//	
		// public boolean accept(Object obj) {
		// return e instanceof WorkProductDescriptor
		// && ((WorkProductDescriptor) e).getWorkProduct() instanceof
		// Deliverable;
		// }
		// };
		// }

		if (childFilter != null) {
			return checkNameInScope(adapterFactory, parent, e, nameFeature, newName,
					childFilter, suppression, ignoreSuppressed);
		}

		return null;
	}
	
	private static String checkEmpty(Object e, String newName) {
		// skip checking on activity that is a extender or local contributor
		//
		if(e instanceof Activity && ProcessUtil.isExtendingOrLocallyContributing((BreakdownElement) e)) {
			return null;
		}
		
		String elementType;
		if (e instanceof NamedElement) {
			elementType = TngUtil.getTypeText((NamedElement) e);
		} else {
			elementType = ELEMENT_TEXT;
		}
		if (newName == null || newName.trim().length() == 0) {			
			return NLS.bind(LibraryEditResources.emptyElementNameError_msg,
					StrUtil.toLower(elementType));
		}
		return null;
	}

	/**
	 * Used by
	 * {@link #checkName(AdapterFactory, BreakdownElement, EStructuralFeature, String, Suppression, boolean) checkName()}
	 * 
	 * @param e
	 * @return
	 */
	private static Class chooseType(BreakdownElement e) {
		if (e instanceof Activity) {
			return Activity.class;
		} else if (e instanceof TaskDescriptor) {
			return TaskDescriptor.class;
		} else if (e instanceof RoleDescriptor) {
			return RoleDescriptor.class;
		} else if (e instanceof WorkProductDescriptor) {
			return WorkProductDescriptor.class;
		} else {
			return e.getClass();
		}
		// return BreakdownElement.class;
	}

	private static String checkNameInScope(AdapterFactory adapterFactory,
			Object currentParent, BreakdownElement e,
			EStructuralFeature feature, String name, IFilter childFilter,
			Suppression suppression, boolean ignoreSuppressed) {
		// check up
		for (Object parent = currentParent; parent != null;) {
			String msg = checkName(adapterFactory, parent, e, childFilter,
					feature, name, suppression, ignoreSuppressed);
			if (msg != null)
				return msg;
			ITreeItemContentProvider itemProvider = (ITreeItemContentProvider) adapterFactory
					.adapt(parent, ITreeItemContentProvider.class);
			parent = itemProvider.getParent(parent);
		}

		// check down
		if (currentParent != null) {
			Iterator iter = new AdapterFactoryTreeIterator(adapterFactory,
					currentParent, false);
			while (iter.hasNext()) {
				Object child = TngUtil.unwrap(iter.next());
				if (child != e && childFilter.accept(child)) {
					String childName = (String) ((EObject) child).eGet(feature);
					if (name.equalsIgnoreCase(childName)) {
						// return I18nUtil.formatString(RESOURCE_BUNDLE, key,
						// data);
						return NLS
								.bind(
										LibraryEditResources.duplicateElementNameError_msg,
										name);
					}

				}
			}
		}

		return null;
	}

	public static String checkName(AdapterFactory adapterFactory,
			final BreakdownElement e, EStructuralFeature feature, String name,
			Suppression suppression) {
		return checkName(adapterFactory, e, feature, name, suppression, false);
	}

	/**
	 * Checks the name or presentation name of a breakdown element that is
	 * already part of a process.
	 * 
	 * @param adapterFactory
	 * @param e
	 * @param feature
	 * @param name
	 * @param suppression
	 * @param ignoreSuppressed
	 * @return
	 */
	public static String checkName(AdapterFactory adapterFactory,
			final BreakdownElement e, EStructuralFeature feature, String name,
			Suppression suppression, boolean ignoreSuppressed) 
	{
		return checkName(adapterFactory, (Object)null, e, (Class)null, feature, name, suppression, ignoreSuppressed);
	}
	
	public static boolean canHaveEmptyPresentationName(DescribableElement e) {
		if(e instanceof VariabilityElement) {
			VariabilityType vType = ((VariabilityElement)e).getVariabilityType();
			return vType == VariabilityType.EXTENDS_LITERAL
				|| vType == VariabilityType.CONTRIBUTES_LITERAL
				|| vType == VariabilityType.LOCAL_CONTRIBUTION_LITERAL;			
		}
		return false;	
	}
	
	public static boolean checkFilePathLength(
			MethodElement parentElementWithResource,
			MethodElement element,
			String name,
			int maxLength,
			String[] filePathName) {
		Resource res = parentElementWithResource.eResource();
		URI uri = res.getURI();
		if (filePathName != null && filePathName.length >= 1) {
			//To do: calculate path
			//filePathName[0] = ??
		}		
		
		int parentResLen = uri.toFileString().length();		
		int localGroupLen = 20;
		if (parentElementWithResource instanceof MethodLibrary) {
			localGroupLen = 0;
		} else if (element instanceof Role) {
			localGroupLen = 5;		//"roles"
		} else if (element instanceof CapabilityPattern) {
			localGroupLen = 18;		//"capabilitypatterns"
		}
		//More else if here
		
		int totalLen = parentResLen + localGroupLen + name.length();		
		return totalLen <= maxLength;	
	}
}
