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

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.DiagnosticChain;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EObjectValidator;
import org.eclipse.emf.edit.provider.AdapterFactoryTreeIterator;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.emf.validation.model.Category;
import org.eclipse.emf.validation.model.EvaluationMode;
import org.eclipse.emf.validation.model.IConstraintStatus;
import org.eclipse.emf.validation.service.IBatchValidator;
import org.eclipse.emf.validation.service.IConstraintDescriptor;
import org.eclipse.emf.validation.service.IConstraintFilter;
import org.eclipse.emf.validation.service.ModelValidationService;
import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.library.edit.IAdapterFactoryProvider;
import org.eclipse.epf.library.edit.process.DescribableElementWrapperItemProvider;
import org.eclipse.epf.library.edit.process.IBSItemProvider;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.edit.validation.DependencyChecker;
import org.eclipse.epf.library.edit.validation.DependencyValidationMgr;
import org.eclipse.epf.library.edit.validation.IValidator;
import org.eclipse.epf.library.edit.validation.IValidatorFactory;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.DescribableElement;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.NamedElement;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.RoleDescriptor;
import org.eclipse.epf.uma.TeamProfile;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.WorkProductDescriptor;
import org.eclipse.epf.validation.constraints.LibraryTraversalStrategy;
import org.eclipse.epf.validation.util.ValidationStatus;

/**
 * An adapter that plugs the EMF Model Validation Service API into the
 * {@link org.eclipse.emf.ecore.EValidator} API.
 * 
 * @author Phong Nguyen Le
 * @since 1.1
 */
public class LibraryEValidator extends EObjectValidator {
	private static final boolean DEBUG = Activator.getDefault().isDebugging();
	private static final Map featureToPropertyMap = createFeatureToAttributeMap();

	public static final String CTX_ADAPTER_FACTORY_PROVIDER = "CTX_ADAPTER_FACTORY_PROVIDER"; //$NON-NLS-1$
	public static final String CTX_DEPENDENCY_VALIDATION_MGR = "CTX_DEPENDENCY_VALIDATION_MGR"; //$NON-NLS-1$
	public static final String CTX_CONSTRAINT_FILTER = "CTX_CONSTRAINT_FILTER"; //$NON-NLS-1$
	
	public static final String CONSTRAINT_CATEGORY = "org.eclipse.epf.validation.library.category"; //$NON-NLS-1$

	private static Map createFeatureToAttributeMap() {
		Map map = new HashMap();
		map.put(UmaPackage.Literals.NAMED_ELEMENT__NAME, IBSItemProvider.COL_NAME);
		map.put(UmaPackage.Literals.METHOD_ELEMENT__PRESENTATION_NAME, IBSItemProvider.COL_PRESENTATION_NAME);
		return map;
	}
	
	/**
	 * Model Validation Service interface for batch validation of EMF elements.
	 */
	private final IBatchValidator batchValidator;

	/**
	 * Initializes me.
	 */
	public LibraryEValidator() {
		super();

		batchValidator = (IBatchValidator) ModelValidationService.getInstance()
				.newValidator(EvaluationMode.BATCH);
		batchValidator.setIncludeLiveConstraints(true);
		batchValidator.setReportSuccesses(false);
		batchValidator.addConstraintFilter(new IConstraintFilter() {

			public boolean accept(IConstraintDescriptor constraint,
					EObject target) {
				Set<Category> categories = constraint.getCategories();
				if(categories != null && !categories.isEmpty()) {
					for (Iterator<Category> iterator = categories.iterator(); iterator
							.hasNext();) {
						Category category = (Category) iterator.next();
						if(CONSTRAINT_CATEGORY.equals(category.getId())) {
							return true;
						}
					}
				}
				return false;
			}
			
		});
	}

	public boolean validate(EObject eObject, DiagnosticChain diagnostics,
			Map context) {
		return validate(eObject.eClass(), eObject, diagnostics, context);
	}

	/**
	 * Implements validation by delegation to the EMF validation framework.
	 */
	public boolean validate(EClass eClass, EObject eObject,
			DiagnosticChain diagnostics, Map context) {
		// first, do whatever the basic EcoreValidator does
		// super.validate(eClass, eObject, diagnostics, context);

		IStatus status = Status.OK_STATUS;

		boolean circularCheckOk = true;
		DependencyValidationMgr mgr = (DependencyValidationMgr) context.get(CTX_DEPENDENCY_VALIDATION_MGR);
		if (DependencyChecker.newCheck && mgr != null && 
				(eObject instanceof VariabilityElement || eObject instanceof MethodPlugin)) {
			status = mgr.checkCircularDependnecy((MethodElement) eObject);
			if(!status.isOK()) {
				circularCheckOk = false;
				String msg = status.getMessage();
				if(StrUtil.isBlank(msg)) {
					//msg = NLS.bind(ValidationResources.circularDependency_error, ref.getEContainingClass().getName(), ref.getName());
					msg = ValidationResources.circularDependency_error;
				}
				appendDiagnostics(status, diagnostics);
			}
		}
		
		// no point in validating if we can't report results
		if (diagnostics != null) {
			// if EMF Mode Validation Service already covered the sub-tree,
			// which it does for efficient computation and error reporting,
			// then don't repeat (the Diagnostician does the recursion
			// externally). If there is no context map, then we can't
			// help it
			if (!hasProcessed(eObject, context)) {
				if (getTraversalType(context) == LibraryTraversalStrategy.DEEP) {
					batchValidator
							.setTraversalStrategy(LibraryTraversalStrategy.deepTraversalStrategy);
				}
				
				IConstraintFilter filter = (IConstraintFilter) context.get(CTX_CONSTRAINT_FILTER);
				if(filter != null) {
					batchValidator.addConstraintFilter(filter);
				}
				try {
					status = batchValidator.validate(eObject,
							new NullProgressMonitor());
				} finally {
					if (filter != null) {
						batchValidator.removeConstraintFilter(filter);
					}
				}

				processed(eObject, context, status);

				appendDiagnostics(status, diagnostics);
			}
		}

		if (eObject instanceof ProcessComponent) {
			Process proc = ((ProcessComponent) eObject).getProcess();
			if (proc != null) {
				validateProcess(proc, diagnostics, context);
			}
		}

		return circularCheckOk && status.isOK();
	}
	
	/**
	 * @param proc
	 * @param diagnostics
	 * @param context
	 */
	public void validateProcess(Process proc, final DiagnosticChain diagnostics,
			Map context) {
		Object o = context.get(CTX_ADAPTER_FACTORY_PROVIDER);
		if (!(o instanceof IAdapterFactoryProvider)) {
			return;
		}

		class FilteredAdapterFactoryTreeIterator extends AdapterFactoryTreeIterator {
			
			public FilteredAdapterFactoryTreeIterator(AdapterFactory adapterFactory, Object object) {
				super(adapterFactory, object);
			}
			
			protected boolean accept(Object child) {
				return child instanceof NamedElement;
			}
			
			/**
			 * Comment for <code>serialVersionUID</code>
			 */
			private static final long serialVersionUID = 0L;

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.emf.edit.provider.AdapterFactoryTreeIterator#getChildren(java.lang.Object)
			 */
			protected Iterator getChildren(Object o) {
				ArrayList children = new ArrayList();
				for (Iterator iter = super.getChildren(o); iter.hasNext();) {
					Object child = iter.next();
					if (child instanceof MethodElement
							|| (child instanceof DescribableElementWrapperItemProvider
							&& !((DescribableElementWrapperItemProvider) child).isReadOnly())) {
						children.add(child);
						child = TngUtil.unwrap(child);
					}
					if (accept(child)) {
						try {
							ArrayList features = new ArrayList();
							features.add(UmaPackage.Literals.NAMED_ELEMENT__NAME);
							if(child instanceof DescribableElement) {
								features.add(UmaPackage.Literals.METHOD_ELEMENT__PRESENTATION_NAME);
							}
							NamedElement e = (NamedElement) child;
							if (e instanceof BreakdownElement) {
								//continue;
							}
							if(DEBUG) {
								System.out
										.println("FilteredAdapterFactoryTreeIterator.getChildren(): validating '" + e.getName() + "'"); //$NON-NLS-1$ //$NON-NLS-2$
							}
							for (Iterator iterator = features.iterator(); iterator
									.hasNext();) {
								EStructuralFeature feature = (EStructuralFeature) iterator.next();
								IValidator validator = IValidatorFactory.INSTANCE
										.createValidator(o, null,
												(EObject) child, feature,
												adapterFactory);
								Object itemProvider = adapterFactory.adapt(child, ITreeItemContentProvider.class);
								String prop = (String) featureToPropertyMap.get(feature);
								String name;
								if(itemProvider instanceof IBSItemProvider && prop != null) {
									name = ((IBSItemProvider)itemProvider).getAttribute(child, prop);
								}
								else {
									name = (String) e.eGet(feature);
								}
								String msg = validator.isValid(name);
								if (msg != null) {
									appendDiagnostics(new ValidationStatus(
											IStatus.ERROR, 0, msg, e, feature),
											diagnostics);
								}
							}
						} catch (Exception e) {

						}
					}
				}				
				return children.iterator();
			}
		};
		IAdapterFactoryProvider provider = (IAdapterFactoryProvider) o;
		Iterator iterator = new FilteredAdapterFactoryTreeIterator(provider
				.getWBSAdapterFactory(), proc);
		for (; iterator.hasNext(); iterator.next())
			;
		
		iterator = new FilteredAdapterFactoryTreeIterator(provider.getTBSAdapterFactory(), proc) {
			/**
			 * Comment for <code>serialVersionUID</code>
			 */
			private static final long serialVersionUID = 1L;

			/* (non-Javadoc)
			 * @see #accept(java.lang.Object)
			 */
			protected boolean accept(Object child) {
				return child instanceof RoleDescriptor || child instanceof TeamProfile;
			}
		};
		for (; iterator.hasNext(); iterator.next())
			;
		
		iterator = new FilteredAdapterFactoryTreeIterator(provider.getWPBSAdapterFactory(), proc) {
			/**
			 * Comment for <code>serialVersionUID</code>
			 */
			private static final long serialVersionUID = 1L;

			/* (non-Javadoc)
			 * @see #accept(java.lang.Object)
			 */
			protected boolean accept(Object child) {
				return child instanceof WorkProductDescriptor;
			}
		};
		for (; iterator.hasNext(); iterator.next())
			;
	}

	private static int getTraversalType(Map context) {
		Object type = context.get(LibraryTraversalStrategy.TRAVERSAL_TYPE);
		return (type instanceof Number && ((Number) type).intValue() == LibraryTraversalStrategy.DEEP) ? LibraryTraversalStrategy.DEEP
				: LibraryTraversalStrategy.SHADOW;
	}

	/**
	 * Direct validation of {@link EDataType}s is not supported by the EMF
	 * validation framework; they are validated indirectly via the
	 * {@link EObject}s that hold their values.
	 */
	public boolean validate(EDataType eDataType, Object value,
			DiagnosticChain diagnostics, Map context) {
		return super.validate(eDataType, value, diagnostics, context);
	}

	/**
	 * If we have a context map, record this object's <code>status</code> in
	 * it so that we will know later that we have processed it and its sub-tree.
	 * 
	 * @param eObject
	 *            an element that we have validated
	 * @param context
	 *            the context (may be <code>null</code>)
	 * @param status
	 *            the element's validation status
	 */
	private void processed(EObject eObject, Map context, IStatus status) {
		if (context != null) {
			context.put(eObject, status);
		}
	}

	/**
	 * Determines whether we have processed this <code>eObject</code> before,
	 * by automatic recursion of the EMF Model Validation Service. This is only
	 * possible if we do, indeed, have a context.
	 * 
	 * @param eObject
	 *            an element to be validated (we hope not)
	 * @param context
	 *            the context (may be <code>null</code>)
	 * @return <code>true</code> if the context is not <code>null</code> and
	 *         the <code>eObject</code> or one of its containers has already
	 *         been validated; <code>false</code>, otherwise
	 */
	private boolean hasProcessed(EObject eObject, Map context) {
		boolean result = false;

		if (context != null) {
			// this is O(NlogN) but there's no helping it
			while (eObject != null) {
				if (context.containsKey(eObject)) {
					result = true;
					eObject = null;
				} else {
					eObject = eObject.eContainer();
				}
			}
		}

		return result;
	}

	/**
	 * Converts a status result from the EMF validation service to diagnostics.
	 * 
	 * @param status
	 *            the EMF validation service's status result
	 * @param diagnostics
	 *            a diagnostic chain to accumulate results on
	 */
	private void appendDiagnostics(IStatus status, DiagnosticChain diagnostics) {
		if (status.isMultiStatus()) {
			IStatus[] children = status.getChildren();

			for (int i = 0; i < children.length; i++) {
				appendDiagnostics(children[i], diagnostics);
			}
		} else if (status instanceof IConstraintStatus) {
			diagnostics.add(new BasicDiagnostic(status.getSeverity(), status
					.getPlugin(), status.getCode(), status.getMessage(),
					((IConstraintStatus) status).getResultLocus().toArray()));
		} else if (status instanceof org.eclipse.epf.library.edit.validation.ValidationStatus) {
			diagnostics.add(new BasicDiagnostic(status.getSeverity(), status
					.getPlugin(), status.getCode(), status.getMessage(),
					new Object[] { ((org.eclipse.epf.library.edit.validation.ValidationStatus) status)
							.getCheckedObject() }));
		} else {
			diagnostics.add(new BasicDiagnostic(status.getSeverity(), status
					.getPlugin(), status.getCode(), status.getMessage(),
					null));
		}
	}

}
