/*******************************************************************************
 * Copyright (c) 2009 by SAP AG, Walldorf. 
 * 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:
 *     SAP AG - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.ws.jaxws.dom.runtime.validation.provider;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jst.ws.jaxws.dom.runtime.GeneralTypesNames;
import org.eclipse.jst.ws.jaxws.dom.runtime.internal.plugin.JaxWsDomRuntimePlugin;
import org.eclipse.jst.ws.jaxws.dom.runtime.internal.validation.provider.TypeAdapter;
import org.eclipse.jst.ws.jaxws.dom.runtime.internal.validation.provider.TypeKey;
import org.eclipse.jst.ws.jaxws.dom.runtime.validation.provider.exceptions.HasInadmisableInnerTypesException;
import org.eclipse.jst.ws.jaxws.dom.runtime.validation.provider.exceptions.InadmissableTypeException;
import org.eclipse.jst.ws.jaxws.dom.runtime.validation.provider.exceptions.InheritanceAndImplementationExecption;
import org.eclipse.jst.ws.jaxws.dom.runtime.validation.provider.exceptions.MultipleImplementationException;
import org.eclipse.jst.ws.jaxws.dom.runtime.validation.provider.exceptions.RemoteObjectException;

/**
 * Provides set of general validation methods which can be reused by subclasses.
 * 
 * @i036509
 */
public abstract class TypeValidator
{
	// there are types from the java.* packages that are supported by the runtime
	// and are known to it without analysis of there structure, therefore they are
	// stored as elementaries.
	private static final Set<String> JAVA_TYPES = new HashSet<String>(); // $JL-COLLECTION$

	// for these java.* types attributes are resolved, i.e they are stored as
	// structure if they contain fields.
	private static final Set<String> ANALYSED_JAVA_TYPES = new HashSet<String>(); // $JL-COLLECTION$

	// these types are allowed to be used in case of multy inheritance
	private static final Set<String> ALLOWED_IN_MULTYINHERITANCE = new HashSet<String>(); // $JL-COLLECTION$

	private Map<TypeKey, IStatus> statusMap = new HashMap<TypeKey, IStatus>();

	// cache of already analyzed types
	private Set<TypeKey> analyzed = new HashSet<TypeKey>();

	static
	{
		// There are types from the java.* packages that are supported by the runtime
		// and are known to it without analysis of there structure, therefore they are
		// stored as elementaries.

		// Date/Time Specific Types
		JAVA_TYPES.add("java.util.Calendar"); //$NON-NLS-1$
		JAVA_TYPES.add("java.util.Date"); //$NON-NLS-1$
		JAVA_TYPES.add("java.util.GregorianCalendar"); //$NON-NLS-1$
		JAVA_TYPES.add("javax.xml.datatype.XMLGregorianCalendar"); //$NON-NLS-1$	

		// Array Based Types
		JAVA_TYPES.add("java.util.ArrayList"); //$NON-NLS-1$
		JAVA_TYPES.add("java.util.HashSet"); //$NON-NLS-1$
		JAVA_TYPES.add("java.util.LinkedList"); //$NON-NLS-1$
		JAVA_TYPES.add("java.util.List"); //$NON-NLS-1$
		JAVA_TYPES.add("java.util.Stack"); //$NON-NLS-1$
		JAVA_TYPES.add("java.util.Vector"); //$NON-NLS-1$

		// Others
		JAVA_TYPES.add("java.math.BigDecimal"); //$NON-NLS-1$
		JAVA_TYPES.add("java.math.BigInteger"); //$NON-NLS-1$
		JAVA_TYPES.add("java.lang.Object"); //$NON-NLS-1$
		JAVA_TYPES.add("javax.xml.namespace.QName"); //$NON-NLS-1$
		JAVA_TYPES.add("java.util.UUID"); //$NON-NLS-1$
		JAVA_TYPES.add("java.net.URI"); //$NON-NLS-1$
		JAVA_TYPES.add("java.awt.Image"); //$NON-NLS-1$
		JAVA_TYPES.add("javax.xml.datatype.Duration"); //$NON-NLS-1$
		JAVA_TYPES.add("javax.xml.transform.Source"); //$NON-NLS-1$
		JAVA_TYPES.add("javax.activation.DataHandler"); //$NON-NLS-1$

		// Java primitive type wrapper classes
		JAVA_TYPES.add("java.lang.String"); //$NON-NLS-1$
		JAVA_TYPES.add("java.lang.Boolean"); //$NON-NLS-1$
		JAVA_TYPES.add("java.lang.Integer"); //$NON-NLS-1$
		JAVA_TYPES.add("java.lang.Character"); //$NON-NLS-1$
		JAVA_TYPES.add("java.lang.Float"); //$NON-NLS-1$
		JAVA_TYPES.add("java.lang.Byte"); //$NON-NLS-1$
		JAVA_TYPES.add("java.lang.Double"); //$NON-NLS-1$
		JAVA_TYPES.add("java.lang.Long"); //$NON-NLS-1$
		JAVA_TYPES.add("java.lang.Short"); //$NON-NLS-1$
		JAVA_TYPES.add("java.lang.Void"); //$NON-NLS-1$

		JAVA_TYPES.add("java.rmi.RemoteException"); //$NON-NLS-1$

		JAVA_TYPES.add("java.io.Serializable"); //$NON-NLS-1$
		JAVA_TYPES.add("java.lang.Cloneable"); //$NON-NLS-1$
		JAVA_TYPES.add("java.lang.Comparable"); //$NON-NLS-1$

		JAVA_TYPES.add("java.util.Map"); //$NON-NLS-1$
		JAVA_TYPES.add("java.util.HashMap"); //$NON-NLS-1$
		JAVA_TYPES.add("java.util.Hashtable"); //$NON-NLS-1$
		JAVA_TYPES.add("java.util.Collection"); //$NON-NLS-1$

		// For these java.* types attributes are resolved, i.e they are stored as
		// structure if they contain fields.
		ANALYSED_JAVA_TYPES.add("java.lang.Exception"); //$NON-NLS-1$
		ANALYSED_JAVA_TYPES.add("java.lang.Throwable"); //$NON-NLS-1$
		ANALYSED_JAVA_TYPES.add("java.lang.StackTraceElement"); //$NON-NLS-1$

		ALLOWED_IN_MULTYINHERITANCE.add(GeneralTypesNames.JAVA_LANG_CLONEABLE); // $NON-NLS$
		ALLOWED_IN_MULTYINHERITANCE.add(GeneralTypesNames.JAVA_IO_SERIALIZABLE); // $NON-NLS$
		ALLOWED_IN_MULTYINHERITANCE.add(GeneralTypesNames.JAVA_LANG_COMPARABLE); // $NON-NLS$
	}

	protected abstract void doValidate(TypeAdapter type) throws InadmissableTypeException, JavaModelException;

	/**
	 * Validates <code>type</code>. The first step is tho check the cache if this type has been checked already. If yes the previuos validation
	 * result is returned if no a check is performed and the result is chached. Internally calls doValidate(type) which should be implemented by
	 * extending classes.
	 * 
	 * @param type -
	 *            checked type
	 * @throws InadmissableTypeException
	 * @throws JavaModelException
	 */
	public void validate(IType type) throws InadmissableTypeException, JavaModelException
	{
		analyzed.clear();
		validateInternal(new TypeAdapter(type));
	}

	/**
	 * Validates <code>type</code>. The first step is tho check the cache if this type has been checked already. If yes the previuos validation
	 * result is returned if no a check is performed and the result is chached. Internally calls doValidate(type) which should be implemented by
	 * extending classes.
	 * 
	 * @param type -
	 *            checked type
	 * @throws InadmissableTypeException
	 * @throws JavaModelException
	 */
	protected void validateInternal(TypeAdapter type) throws InadmissableTypeException, JavaModelException
	{
		final TypeKey key = new TypeKey(type.getProjectName(), type.getQualifiedName());

		// check for circular type check
		if (analyzed.contains(key))
		{
			return;
		}

		analyzed.add(key);

		final IStatus status = statusMap.get(key);
		if (status != null)
		{
			if (status.getSeverity() == IStatus.OK)
			{
				return;
			}

			throw (InadmissableTypeException) status.getException();
		}

		try
		{
			doValidate(type);
			statusMap.put(key, prepareStatus(null));
		} catch (InadmissableTypeException e)
		{
			statusMap.put(key, prepareStatus(e));
			throw e;
		}
	}

	/**
	 * if <code>throwable</code> is null prepares status with severity IStatus.OK and empty message. If <code>throwable</code> is not null
	 * prepares status with severity IStatus.ERROR and message the contained in <code>throwable</code> error message.
	 * 
	 * @param throwable
	 * @return IStatus with severity IStatus.OK if <tt>throwable</tt> is null , or IStatus.ERROR including error message decribing the problem.
	 */
	private IStatus prepareStatus(Throwable throwable)
	{
		final IStatus status = new Status((throwable == null) ? IStatus.OK : IStatus.ERROR, JaxWsDomRuntimePlugin.PLUGIN_ID, IStatus.OK,
										(throwable == null) ? "" : throwable.getMessage(), //$NON-NLS-1$
										throwable);

		return status;
	}

	/**
	 * Defines if <code>typeName</code> one form java.* or javax.* packages.
	 * 
	 * @param typeName
	 * @return <tt>true</tt> if <tt>typeName</tt> is from java standard classes.
	 */
	protected boolean isJavaType(String typeName)
	{
		return typeName.startsWith("java.") //$NON-NLS-1$
										|| typeName.startsWith("javax."); //$NON-NLS-1$
	}

	/**
	 * Defines if <code>typeName</code> is allowed java type. The list of allowed java types can be found in static section of this class.
	 * 
	 * @param typeName
	 * @return <tt>true</tt> if <tt>typeName</tt> is allowed to be used in Web Service.
	 */
	protected boolean isAllowedJavaType(String typeName)
	{
		return JAVA_TYPES.contains(typeName) || ANALYSED_JAVA_TYPES.contains(typeName);
	}

	/**
	 * Checks if <code>type</code> implements java.rmi.Remote interface.
	 * 
	 * @param type
	 * @throws InadmissableTypeException
	 * @throws JavaModelException
	 */
	protected void checkRemoteNotImplemented(TypeAdapter type) throws InadmissableTypeException, JavaModelException
	{
		if (type.isImplementing(GeneralTypesNames.JAVA_RMI_REMOTE))
		{
			throw new RemoteObjectException(type.getQualifiedName());
		}
	}

	/**
	 * Checks if <code>type</code> implements multiple interfaces. Classes that extend class other than java.lang.Object should not implement any
	 * interface. Classes that extend java.lang.Object can implement only one interface.<br>
	 * <br>
	 * Note: The following interfaces are skipped from check:<br>
	 * <ul>
	 * java.io.Serializble<br>
	 * java.lang.Clonable<br>
	 * java.lang.Comparable<br>
	 * </ul>
	 * 
	 * @param type
	 * @throws InadmissableTypeException
	 * @throws JavaModelException
	 */
	protected void checkMultipleInheritance(TypeAdapter type) throws InadmissableTypeException, JavaModelException
	{
		List<String> interfaceNames = type.getInterfaceNames();
		final String superClassName = type.getSuperClassName();
		if (superClassName == null || superClassName.equals(GeneralTypesNames.JAVA_LANG_OBJECT)
										|| superClassName.equals(GeneralTypesNames.JAVA_LANG_EXCEPTION))
		{
			if (!checkInterfaceImplementationCount(interfaceNames, 1))
			{
				throw new MultipleImplementationException(type.getQualifiedName(), interfaceNames.get(0), interfaceNames.get(1));
			}
		} else
		{
			if (!checkInterfaceImplementationCount(interfaceNames, 0))
			{
				throw new InheritanceAndImplementationExecption(type.getQualifiedName(), superClassName);
			}

			checkMultipleInheritance(type.getSuperClassType());
		}
	}

	/**
	 * Checks if <code>interfaceNames</code> are more than <code>maxAllowed</code> interfaces. Note: The following interfaces are skipped from
	 * check:<br>
	 * <ul>
	 * java.io.Serializble<br>
	 * java.lang.Clonable<br>
	 * java.lang.Comparable<br>
	 * </ul>
	 * 
	 * @param interfaceNames
	 * @param maxAllowed -
	 *            number of maximum allowed implementations
	 */
	protected boolean checkInterfaceImplementationCount(List<String> interfaceNames, int maxAllowed)
	{
		if (interfaceNames == null || interfaceNames.size() == 0)
		{
			return true;
		}

		int noneAllowedInterfaceCount = 0;
		for (String interfaceName : interfaceNames)
		{
			if (ALLOWED_IN_MULTYINHERITANCE.contains(interfaceName))
			{
				continue;
			}

			noneAllowedInterfaceCount++;
			if (noneAllowedInterfaceCount > maxAllowed)
			{
				return false;
			}
		}

		return true;
	}

	/**
	 * Inadmissable are member classes that are not "public static".
	 * 
	 * @param type
	 * @throws HasInadmisableInnerTypesException
	 * @throws JavaModelException
	 */
	protected void checkForInadmissableInnerClasses(TypeAdapter type) throws HasInadmisableInnerTypesException, JavaModelException
	{
		if (type.hasNonStaticOrNonPublicInnerTypes())
		{
			throw new HasInadmisableInnerTypesException(type.getQualifiedName());
		}
	}
}
