/***********************************************************************
 * 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();

		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 = 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) {
			createInjectionTarget(refName, ref.getInjectionTargets(), annotation);
		}
	}

	private void createInjectionTarget(String refName, List<InjectionTarget> injectionTargets, IAnnotation annotation) {
		InjectionTarget injectionTarget = JavaeeFactory.eINSTANCE.createInjectionTarget();
		int index = refName.indexOf('/');
		if (index != -1) {
			injectionTarget.setInjectionTargetClass(refName.substring(0, index));
			injectionTarget.setInjectionTargetName(refName.substring(index + 1));
		} else {
			injectionTarget.setInjectionTargetName(refName);
			injectionTarget.setInjectionTargetClass("");//$NON-NLS-1$
		}
		injectionTargets.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 refName = (String) getAnnotatedValue("name", pairs);
		if (refName == null)
			refName = getMemberQualifiedName(member);
		ResourceRef ref = JavaeeFactory.eINSTANCE.createResourceRef();
		ref.setResRefName(refName);
		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);
		}
		if (member.getElementType() == IJavaElement.METHOD || member.getElementType() == IJavaElement.FIELD) {
			createInjectionTarget(refName, ref.getInjectionTargets(), annotation);
		}
		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);
		}
	}
}
