/***********************************************************************
 * Copyright (c) 2008 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.jee.model.internal.common;

import java.util.Collection;
import java.util.List;

import org.eclipse.jdt.core.IAnnotation;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IImportDeclaration;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMemberValuePair;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jst.javaee.core.Description;
import org.eclipse.jst.javaee.core.EjbLocalRef;
import org.eclipse.jst.javaee.core.InjectionTarget;
import org.eclipse.jst.javaee.core.JavaeeFactory;
import org.eclipse.jst.javaee.core.ResAuthType;
import org.eclipse.jst.javaee.core.ResSharingScopeType;
import org.eclipse.jst.javaee.core.ResourceRef;
import org.eclipse.jst.javaee.core.RunAs;
import org.eclipse.jst.javaee.core.SecurityRole;
import org.eclipse.jst.javaee.core.SecurityRoleRef;
import org.eclipse.jst.javaee.ejb.SessionBean;

/**
 * @author Kiril Mitov k.mitov@sap.com
 * 
 */
public abstract class AbstractAnnotationFactory {

	/**
	 * @param value
	 * @return true if "value" is an array of objects.
	 */
	protected static boolean isArrayOfObject(Object value) {
		return Object[].class.isInstance(value);
	}

	protected Object getAnnotatedValue(String name, IMemberValuePair[] memberValuePairs) throws JavaModelException {
		for (IMemberValuePair pair : memberValuePairs) {
			if (name.equals(pair.getMemberName())) {
				return pair.getValue();
			}
		}
		return null;
	}

	protected boolean containsImport(ICompilationUnit unit, String importt) throws JavaModelException {
		for (IImportDeclaration declaration : unit.getImports()) {
			if (declaration.getElementName().equals(importt))
				return true;
		}
		return false;
	}

	/**
	 * Resolve the given <code>toResolve</code> string to an IType in the
	 * context of <code>declaringType</code>
	 * 
	 * @param declaringType
	 * @param toResolve
	 *            the type that should be resolved.
	 * @return the resolved type or <code>null</code> if such type can not be
	 *         resolved. Returns <code>null</code> if toResolve is
	 *         <code>null</code>
	 * @throws JavaModelException
	 */
	protected IType resolveType(IType declaringType, String toResolve) throws JavaModelException {
		if (toResolve == null)
			return null;
		String[][] fullTypeName = declaringType.resolveType(toResolve);
		if (fullTypeName != null)
			return declaringType.getJavaProject().findType(fullTypeName[0][0], fullTypeName[0][1]);
		return null;
	}

	protected void processEjbAnnotation(IAnnotation annotation, List<EjbLocalRef> localRefs, IMember member,
			Collection<IType> dependedTypes) throws JavaModelException {
		int memberType = member.getElementType();
		IMemberValuePair[] pairs = annotation.getMemberValuePairs();
		IType declaringType = (IType) (member.getElementType() == IJavaElement.TYPE ? member : member
				.getDeclaringType());

		String beanInterfaceValue = (String) getAnnotatedValue("beanInterface", pairs);
		beanInterfaceValue = internalProcessInjection(beanInterfaceValue, member, dependedTypes);
		if (beanInterfaceValue == null)
			return;

		/*
		 * The name of the reference should be the value of the "name"
		 * attribute. If there is no "name" attribute then the name of the
		 * reference is the qualified name of the member. Check this at
		 * Enterprise Java Beans, 3.0, Section 14.1.5.3
		 */
		String refName = (String) getAnnotatedValue("name", pairs);
		if (refName == null) {
			refName = getMemberQualifiedName(member);
		}
		EjbLocalRef ref = ref = JavaeeFactory.eINSTANCE.createEjbLocalRef();
		ref.setEjbRefName(refName);
		localRefs.add(ref);
		ref.setLocal(beanInterfaceValue);
		ref.setLocalHome(beanInterfaceValue);
		ref.setEjbLink((String) getAnnotatedValue("beanName", pairs));
		ref.setMappedName((String) getAnnotatedValue("mappedName", pairs));
		if (memberType == IJavaElement.METHOD || memberType == IJavaElement.FIELD) {
			InjectionTarget injectionTarget = JavaeeFactory.eINSTANCE.createInjectionTarget();
			int index = refName.indexOf('/');
			injectionTarget.setInjectionTargetClass(refName.substring(0, index));
			injectionTarget.setInjectionTargetName(refName.substring(index + 1));
			ref.getInjectionTargets().add(injectionTarget);
		}
	}

	/**
	 * Resource annotation can be placed on class, method, field.
	 * 
	 * Checks are made if the resource annotation is valid.
	 * <p>
	 * If on class there should be a "type" attribute. If on method the method
	 * must have one param with type that is an interface. If on field the field
	 * type must be an interface.
	 * 
	 * If the type of the method/field can not be resolved the result will
	 * contain the unresolved value.
	 * 
	 * In case the type of method/field is array, wildcard, simple type this is
	 * not a place for the annotation.
	 * </p>
	 * 
	 * <p>
	 * In case of method/field the type specified using the "type" attribute has
	 * a higher priority that the method/field type.
	 * </p>
	 * 
	 * <p>
	 * Only resolved types are added to dependedTypes
	 * </p>
	 * 
	 * @param sessionBean
	 * @param member
	 * @param annotation
	 * @param dependedTypes
	 * @throws JavaModelException
	 */
	protected void processResourceRefAnnotation(IAnnotation annotation, List<ResourceRef> resourceRefs, IMember member,
			Collection<IType> dependedTypes) throws JavaModelException {

		IMemberValuePair[] pairs = annotation.getMemberValuePairs();
		String specifiedType = (String) getAnnotatedValue("type", pairs);
		specifiedType = internalProcessInjection(specifiedType, member, dependedTypes);
		if (specifiedType == null)
			return;
		String name = (String) getAnnotatedValue("name", pairs);
		if (name == null)
			name = getMemberQualifiedName(member);
		ResourceRef ref = JavaeeFactory.eINSTANCE.createResourceRef();
		ref.setResRefName(name);
		ref.setResType(specifiedType);
		ref.setMappedName((String) getAnnotatedValue("mappedName", pairs));
		String description = (String) getAnnotatedValue("description", pairs);
		if (description != null) {
			Description desc = JavaeeFactory.eINSTANCE.createDescription();
			desc.setValue(description);
			ref.getDescriptions().clear();
			ref.getDescriptions().add(desc);
		}
		String value = (String) getAnnotatedValue("authenticationType", pairs);
		/*
		 * the default value is AuthenticationType.APPLICATION which is handled
		 * by the EMF. no need to check for this value
		 */
		if ("AuthenticationType.CONTAINER".equals(value)) {
			ref.setResAuth(ResAuthType.CONTAINER_LITERAL);
		} else if ("CONTAINER".equals(value)
				&& containsImport(member.getCompilationUnit(), "AuthenticationType.CONTAINER")) {
			ref.setResAuth(ResAuthType.CONTAINER_LITERAL);
		}
		Boolean shareable = (Boolean) getAnnotatedValue("shareable", pairs);
		/*
		 * The default value for sharable is true. Check and process only
		 * unsharable
		 */
		if (Boolean.FALSE.equals(shareable))
			ref.setResSharingScope(ResSharingScopeType.UNSHAREABLE_LITERAL);

		resourceRefs.add(ref);
	}

	/**
	 * The method has the task of processing the member along with the specified
	 * member and return a String. The result is to be used as a reference value
	 * for the injection on this member. Usage are the
	 * 
	 * @EJB and
	 * @Resource annotations.
	 * 
	 * <p>
	 * If the specifiedType is <code>null</code> and member is of type
	 * IJavaElement.TYPE the method returns <code>null</code>
	 * </p>
	 * 
	 * <p>
	 * If the type of the member can be resolved and is an interface the method
	 * returns <code>null</code>. Here the "type" of the member is the result
	 * from {@link #getUnresolvedType(IMember)}
	 * </p>
	 * 
	 * 
	 * Only if the specifiedType can be calculated and is resolved it is added
	 * to the dependedTypes. If the specifiedType can not be resolved nothing is
	 * added to dependedTypes.
	 * 
	 * @see {@link #processEjbAnnotation(IAnnotation, SessionBean, IMember, Collection)}
	 * @see #processResourceRefAnnotation(SessionBean, IMember, IAnnotation,
	 *      Collection)
	 * 
	 * @param specifiedType
	 * @param member
	 * @param dependedTypes
	 * @return
	 * @throws JavaModelException
	 */
	private String internalProcessInjection(String specifiedType, IMember member, Collection<IType> dependedTypes)
			throws JavaModelException {
		boolean methodOrField = member.getElementType() == IJavaElement.METHOD
				|| member.getElementType() == IJavaElement.FIELD;
		IType declaringType = (IType) (member.getElementType() == IJavaElement.TYPE ? member : member
				.getDeclaringType());
		String memberType = getUnresolvedType(member);
		// not type for this member can be retrieved. If member is a method or
		// field this means there is an error.
		if (getClassTypeSignature(memberType) == null && methodOrField)
			return null;

		// both type are null. This is not a valid case. This will hapen for a
		// type without specified type.
		if (specifiedType == null && memberType == null)
			return null;

		IType resolvedType = resolveType(declaringType, memberType);
		// we were able to get a type for the param of a method or type of
		// a field.
		// check if it is an interface. It might not be resolved, but we have a
		// value
		// for unresolved.
		if (methodOrField) {
			// if the resolved type is not null and it is not an interface this
			// annotation is not valid
			if (resolvedType != null) {
				if (resolvedType.isInterface())
					memberType = resolvedType.getFullyQualifiedName();
				else
					// invalid - if the method is with param that is not an
					// interface. Or the type of the field is not an interface.
					return null;
			}
		}
		// from now one use only the specified type for type resolving. If there
		// is no specified type use the member type. The check for whether they
		// were both null is previously made
		IType resolvedSpecifiedType = null;
		if (specifiedType == null) {
			specifiedType = memberType;
			resolvedSpecifiedType = resolvedType;
		} else
			resolvedSpecifiedType = resolveType(declaringType, specifiedType);
		if (resolvedSpecifiedType != null) {
			if (resolvedSpecifiedType.isInterface()) {
				specifiedType = resolvedSpecifiedType.getFullyQualifiedName();
				dependedTypes.add(resolvedSpecifiedType);
			} else
				// we have resolved the specified type and it is not an
				// interface. Not a valid annotation.
				return null;
		}
		return specifiedType;
	}

	/**
	 * This method returns a qualified name for this member. The name is to be
	 * used as ejb-ref-name.
	 * 
	 * If the member is a type then fullyQualifiedName of the type is returned.
	 * 
	 * If the member is a <code>field</code> declared in a <code>type</code>
	 * then the result is
	 * <code>type.getFullyQualifiedName() +"/" + field.elementName</code>
	 * 
	 * If the member is a <code>method</code> declared in a <code>type</code>
	 * and method name begins with "set" then: for type name =
	 * "org.eclipse.Bean" and method name = "setMethodOne()" the result is
	 * "org.eclipse.Bean/methodOne"
	 * 
	 * Check this at Enterprise Java Beans, 3.0, Section 14.1.5.3
	 * 
	 * @param member
	 * @return
	 */
	private String getMemberQualifiedName(IMember member) {
		String memberName = member.getElementName();
		int elementType = member.getElementType();
		if (elementType == IJavaElement.METHOD && memberName.startsWith("set")) {
			char ch = Character.toLowerCase(memberName.charAt(3));
			memberName = ch + memberName.substring(4);
		}
		return elementType == IJavaElement.TYPE ? ((IType) member).getFullyQualifiedName() : member.getDeclaringType()
				.getFullyQualifiedName()
				+ "/" + memberName;
	}

	/**
	 * Return the javaee type of this member. For types return <code>null</code>.
	 * For methods with one param return the java type of this param. For fields
	 * return the return the java type of the field.
	 * 
	 * If the result is <code>null</code> then this member is not valid and a
	 * javaee type can not be returned. This may happen for a method with more
	 * then one param or for a field with a class type or primitive type
	 * 
	 * @param member
	 * @param memberType
	 * 
	 * @return
	 * @throws JavaModelException
	 */
	private String getUnresolvedType(IMember member) throws JavaModelException {
		int memberType = member.getElementType();
		IType declaringType = member.getDeclaringType();
		String unresolvedTypeName = null;
		if (memberType == IJavaElement.FIELD) {
			unresolvedTypeName = Signature.toString(((IField) member).getTypeSignature());
		} else if (memberType == IJavaElement.METHOD) {
			IMethod method = (IMethod) member;
			if (method.getNumberOfParameters() != 1)
				return null;
			unresolvedTypeName = Signature.toString(method.getParameterTypes()[0]);
		} else if (memberType == IJavaElement.TYPE)
			return null;
		return unresolvedTypeName;
	}

	/**
	 * Returns the type signature for toResolve only if toResolve is a class or
	 * interface.
	 * 
	 * @param toResolve
	 * @return <code>null</code> if toResolve is <code>null</code> or simple
	 *         type, array type, wildcard type
	 * 
	 */
	private String getClassTypeSignature(String toResolve) {
		if (toResolve == null)
			return null;
		toResolve = Signature.createTypeSignature(toResolve, false);
		if (Signature.getTypeSignatureKind(toResolve) != Signature.CLASS_TYPE_SIGNATURE)
			return null;
		return toResolve;
	}

	protected void processDeclareRoles(Result result, List<SecurityRoleRef> securityRoleRefs, IAnnotation annotation,
			IType type) throws JavaModelException {
		IMemberValuePair[] pairs = annotation.getMemberValuePairs();
		Object values = getAnnotatedValue("value", pairs);
		if (!isArrayOfObject(values))
			return;
		for (Object roleName : (Object[]) values) {
			SecurityRole role = JavaeeFactory.eINSTANCE.createSecurityRole();
			role.setRoleName((String) roleName);
			result.getAdditional().add(role);
			SecurityRoleRef ref = JavaeeFactory.eINSTANCE.createSecurityRoleRef();
			ref.setRoleName((String) roleName);
			securityRoleRefs.add(ref);
		}
	}

	protected void processResourcesAnnotation(IAnnotation annotation, List<ResourceRef> resourceRefs, IType type,
			Collection<IType> dependedTypes) throws JavaModelException {
		IMemberValuePair[] pairs = annotation.getMemberValuePairs();
		if (!isArrayOfObject(pairs[0].getValue()))
			return;
		Object[] values = (Object[]) pairs[0].getValue();
		for (Object resourceAnnotation : values) {
			processResourceRefAnnotation((IAnnotation) resourceAnnotation, resourceRefs, type, dependedTypes);
		}
	}

	protected void processRunAs(IAnnotation annotation,RunAs runAs) throws JavaModelException {
		IMemberValuePair[] pairs = annotation.getMemberValuePairs();
		if (pairs.length == 1) {
			String value = (String) getAnnotatedValue("value", pairs);
			runAs.setRoleName(value);
		}
	}
}
