/*******************************************************************************
 * Copyright (c) 2009 Oracle. 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:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.core.internal.resource.java.binary;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Vector;

import org.eclipse.jdt.core.IAnnotation;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaProject;
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.jpt.core.JptCorePlugin;
import org.eclipse.jpt.core.internal.utility.jdt.JPTTools;
import org.eclipse.jpt.core.resource.java.AccessAnnotation;
import org.eclipse.jpt.core.resource.java.AccessType;
import org.eclipse.jpt.core.resource.java.Annotation;
import org.eclipse.jpt.core.resource.java.JavaResourcePersistentAttribute;
import org.eclipse.jpt.core.resource.java.JavaResourcePersistentType;
import org.eclipse.jpt.utility.MethodSignature;
import org.eclipse.jpt.utility.internal.ClassTools;
import org.eclipse.jpt.utility.internal.NameTools;
import org.eclipse.jpt.utility.internal.iterators.CloneIterator;
import org.eclipse.jpt.utility.internal.iterators.CloneListIterator;

/**
 * binary persistent attribute (field or property)
 */
final class BinaryPersistentAttribute
	extends BinaryPersistentMember
	implements JavaResourcePersistentAttribute
{
	private int modifiers;

	private String typeName;

	private boolean typeIsInterface;

	private boolean typeIsEnum;

	private final Vector<String> typeSuperclassNames = new Vector<String>();

	private final Vector<String> typeInterfaceNames = new Vector<String>();

	private final Vector<String> typeTypeArgumentNames = new Vector<String>();


	BinaryPersistentAttribute(JavaResourcePersistentType parent, IField field) {
		this(parent, new FieldAdapter(field));
	}

	BinaryPersistentAttribute(JavaResourcePersistentType parent, IMethod method) {
		this(parent, new MethodAdapter(method));
	}

	private BinaryPersistentAttribute(JavaResourcePersistentType parent, Adapter adapter) {
		super(parent, adapter);
		this.modifiers = this.buildModifiers();
		this.typeName = this.buildTypeName();

		IType type = this.getType();  // shouldn't be an array...
		this.typeIsInterface = this.buildTypeIsInterface(type);
		this.typeIsEnum = this.buildTypeIsEnum(type);
		this.typeSuperclassNames.addAll(this.buildTypeSuperclassNames(type));
		this.typeInterfaceNames.addAll(this.buildTypeInterfaceNames(type));
		this.typeTypeArgumentNames.addAll(this.buildTypeTypeArgumentNames());
	}


	// ******** overrides ********

	@Override
	public void update() {
		super.update();
		this.setModifiers(this.buildModifiers());
		this.setTypeName(this.buildTypeName());

		IType type = this.getType();  // shouldn't be an array...
		this.setTypeIsInterface(this.buildTypeIsInterface(type));
		this.setTypeIsEnum(this.buildTypeIsEnum(type));
		this.setTypeSuperclassNames(this.buildTypeSuperclassNames(type));
		this.setTypeInterfaceNames(this.buildTypeInterfaceNames(type));
		this.setTypeTypeArgumentNames(this.buildTypeTypeArgumentNames());
	}

	@Override
	public void toString(StringBuilder sb) {
		sb.append(this.getName());
	}


	// ********** BinaryPersistentMember implementation **********

	private Adapter getAdapter() {
		return (Adapter) this.adapter;
	}

	@Override
	Annotation buildMappingAnnotation(IAnnotation jdtAnnotation) {
		return this.getAnnotationProvider().buildAttributeMappingAnnotation(this, jdtAnnotation);
	}

	@Override
	Annotation buildSupportingAnnotation(IAnnotation jdtAnnotation) {
		return this.getAnnotationProvider().buildAttributeSupportingAnnotation(this, jdtAnnotation);
	}

	@Override
	Annotation buildNullSupportingAnnotation(String annotationName) {
		return this.getAnnotationProvider().buildNullAttributeSupportingAnnotation(this, annotationName);
	}

	public Annotation getNullMappingAnnotation(String annotationName) {
		return (annotationName == null) ? null : this.buildNullMappingAnnotation(annotationName);
	}

	private Annotation buildNullMappingAnnotation(String annotationName) {
		return this.getAnnotationProvider().buildNullAttributeMappingAnnotation(this, annotationName);
	}

	@Override
	ListIterator<String> validMappingAnnotationNames() {
		return this.getAnnotationProvider().attributeMappingAnnotationNames();
	}

	@Override
	ListIterator<String> validSupportingAnnotationNames() {
		return this.getAnnotationProvider().attributeSupportingAnnotationNames();
	}


	// ********** JavaResourcePersistentAttribute implementation **********

	public String getName() {
		return this.getAdapter().getAttributeName();
	}

	public boolean isField() {
		return this.getAdapter().isField();
	}

	public boolean isProperty() {
		return ! this.isField();
	}

	public boolean isFor(MethodSignature methodSignature, int occurrence) {
		throw new UnsupportedOperationException();
	}

	public boolean hasAnyPersistenceAnnotations() {
		return (this.mappingAnnotationsSize() > 0)
				|| (this.supportingAnnotationsSize() > 0);
	}

	public AccessType getSpecifiedAccess() {
		AccessAnnotation accessAnnotation = (AccessAnnotation) this.getSupportingAnnotation(AccessAnnotation.ANNOTATION_NAME);
		return accessAnnotation == null ? null : accessAnnotation.getValue();
	}

	public boolean typeIsSubTypeOf(String tn) {
		return ((this.typeName != null) && this.typeName.equals(tn))
				|| this.typeInterfaceNames.contains(tn)
				|| this.typeSuperclassNames.contains(tn);
	}

	public boolean typeIsVariablePrimitive() {
		return (this.typeName != null) && ClassTools.classNamedIsVariablePrimitive(this.typeName);
	}

	// ***** modifiers
	public int getModifiers() {
		return this.modifiers;
	}

	private void setModifiers(int modifiers) {
		int old = this.modifiers;
		this.modifiers = modifiers;
		this.firePropertyChanged(MODIFIERS_PROPERTY, old, modifiers);
	}

	/**
	 * zero seems like a reasonable default...
	 */
	private int buildModifiers() {
		try {
			return this.getMember().getFlags();
		} catch (JavaModelException ex) {
			JptCorePlugin.log(ex);
			return 0;
		}
	}

	// ***** type name
	public String getTypeName() {
		return this.typeName;
	}

	private void setTypeName(String typeName) {
		String old = this.typeName;
		this.typeName = typeName;
		this.firePropertyChanged(TYPE_NAME_PROPERTY, old, typeName);
	}

	/**
	 * JARs don't have array types;
	 * also, no generic type parameters
	 */
	private String buildTypeName() {
		return convertTypeSignatureToTypeName(this.getTypeSignature());
	}

	// ***** type is interface
	public boolean typeIsInterface() {
		return this.typeIsInterface;
	}

	private void setTypeIsInterface(boolean typeIsInterface) {
		boolean old = this.typeIsInterface;
		this.typeIsInterface = typeIsInterface;
		this.firePropertyChanged(TYPE_IS_INTERFACE_PROPERTY, old, typeIsInterface);
	}

	private boolean buildTypeIsInterface(IType type) {
		try {
			return (type != null) && type.isInterface();
		} catch (JavaModelException ex) {
			JptCorePlugin.log(ex);
			return false;
		}
	}

	// ***** type is enum
	public boolean typeIsEnum() {
		return this.typeIsEnum;
	}

	private void setTypeIsEnum(boolean typeIsEnum) {
		boolean old = this.typeIsEnum;
		this.typeIsEnum = typeIsEnum;
		this.firePropertyChanged(TYPE_IS_ENUM_PROPERTY, old, typeIsEnum);
	}

	private boolean buildTypeIsEnum(IType type) {
		try {
			return (type != null) && type.isEnum();
		} catch (JavaModelException ex) {
			JptCorePlugin.log(ex);
			return false;
		}
	}

	// ***** type superclass hierarchy
	public ListIterator<String> typeSuperclassNames() {
		return new CloneListIterator<String>(this.typeSuperclassNames);
	}

	public boolean typeSuperclassNamesContains(String superclassName) {
		return this.typeSuperclassNames.contains(superclassName);
	}

	private void setTypeSuperclassNames(List<String> typeSuperclassNames) {
		this.synchronizeList(typeSuperclassNames, this.typeSuperclassNames, TYPE_SUPERCLASS_NAMES_COLLECTION);
	}

	private List<String> buildTypeSuperclassNames(IType type) {
		if (type == null) {
			return Collections.emptyList();
		}

		ArrayList<String> names = new ArrayList<String>();
		type = this.findSuperclass(type);
		while (type != null) {
			names.add(type.getFullyQualifiedName());  // no parameters are included here
			type = this.findSuperclass(type);
		}
		return names;
	}

	// ***** type interface hierarchy
	public Iterator<String> typeInterfaceNames() {
		return new CloneIterator<String>(this.typeInterfaceNames);
	}

	public boolean typeInterfaceNamesContains(String interfaceName) {
		return this.typeInterfaceNames.contains(interfaceName);
	}

	private void setTypeInterfaceNames(Collection<String> typeInterfaceNames) {
		this.synchronizeCollection(typeInterfaceNames, this.typeInterfaceNames, TYPE_INTERFACE_NAMES_COLLECTION);
	}

	private Collection<String> buildTypeInterfaceNames(IType type) {
		if (type == null) {
			return Collections.emptySet();
		}

		HashSet<String> names = new HashSet<String>();
		while (type != null) {
			this.addInterfaceNamesTo(type, names);
			type = this.findSuperclass(type);
		}
		return names;
	}

	private void addInterfaceNamesTo(IType type, HashSet<String> names) {
		for (String interfaceSignature : this.getSuperInterfaceTypeSignatures(type)) {
			String interfaceName = convertTypeSignatureToTypeName(interfaceSignature);
			names.add(interfaceName);
			IType interfaceType = this.findType(interfaceName);
			if (interfaceType != null) {
				this.addInterfaceNamesTo(interfaceType, names);  // recurse
			}
		}
	}

	// ***** type type argument names
	public ListIterator<String> typeTypeArgumentNames() {
		return new CloneListIterator<String>(this.typeTypeArgumentNames);
	}

	public int typeTypeArgumentNamesSize() {
		return this.typeTypeArgumentNames.size();
	}

	public String getTypeTypeArgumentName(int index) {
		return this.typeTypeArgumentNames.get(index);
	}

	private void setTypeTypeArgumentNames(List<String> typeTypeArgumentNames) {
		this.synchronizeList(typeTypeArgumentNames, this.typeTypeArgumentNames, TYPE_TYPE_ARGUMENT_NAMES_COLLECTION);
	}

	/**
	 * these types can be arrays (e.g. "java.lang.String[]");
	 * but they won't have any further nested generic type arguments
	 * (e.g. "java.util.Collection<java.lang.String>")
	 */
	private List<String> buildTypeTypeArgumentNames() {
		String typeSignature = this.getTypeSignature();
		if (typeSignature == null) {
			return Collections.emptyList();
		}

		String[] typeArgumentSignatures = Signature.getTypeArguments(typeSignature);
		if (typeArgumentSignatures.length == 0) {
			return Collections.emptyList();
		}

		ArrayList<String> names = new ArrayList<String>(typeArgumentSignatures.length);
		for (String typeArgumentSignature : typeArgumentSignatures) {
			names.add(convertTypeSignatureToTypeName(typeArgumentSignature));
		}
		return names;
	}


	// ********** convenience methods **********

	private String getTypeSignature() {
		try {
			return this.getAdapter().getTypeSignature();
		} catch (JavaModelException ex) {
			JptCorePlugin.log(ex);
			return null;
		}
	}

	private IType findSuperclass(IType type) {
		return this.findTypeBySignature(this.getSuperclassSignature(type));
	}

	private String getSuperclassSignature(IType type) {
		try {
			return type.getSuperclassTypeSignature();
		} catch (JavaModelException ex) {
			JptCorePlugin.log(ex);
			return null;
		}
	}

	private String[] getSuperInterfaceTypeSignatures(IType type) {
		try {
			return type.getSuperInterfaceTypeSignatures();
		} catch (JavaModelException ex) {
			JptCorePlugin.log(ex);
			return EMPTY_STRING_ARRAY;
		}
	}
	private static final String[] EMPTY_STRING_ARRAY = new String[0];

	private IType findTypeBySignature(String typeSignature) {
		return (typeSignature == null) ? null : this.findType(convertTypeSignatureToTypeName_(typeSignature));
	}

	private IType getType() {
		return (this.typeName == null) ? null : this.findType(this.typeName);
	}

	private IType findType(String fullyQualifiedName) {
		try {
			return this.getJavaProject().findType(fullyQualifiedName);
		} catch (JavaModelException ex) {
			JptCorePlugin.log(ex);
			return null;
		}
	}

	private IJavaProject getJavaProject() {
		return this.getMember().getJavaProject();
	}



	// ********** adapters **********

	/**
	 * Adapt an IField or IMethod.
	 */
	interface Adapter
		extends BinaryPersistentMember.Adapter
	{
		/**
		 * Return the field or getter method's "attribute" name
		 * (e.g. field "foo" -> "foo"; method "getFoo" -> "foo").
		 */
		String getAttributeName();

		/**
		 * Return whether the attribute is a Java field (as opposed to a method).
		 */
		boolean isField();

		/**
		 * Return the attribute's type signature.
		 */
		String getTypeSignature() throws JavaModelException;
	}

	/**
	 * IField adapter
	 */
	static class FieldAdapter
		implements Adapter
	{
		final IField field;

		FieldAdapter(IField field) {
			super();
			this.field = field;
		}

		public IField getMember() {
			return this.field;
		}

		public boolean isPersistable() {
			return this.field.exists() && JPTTools.fieldIsPersistable(new JPTToolsAdapter());
		}

		public IAnnotation[] getAnnotations() throws JavaModelException {
			return this.field.getAnnotations();
		}

		public String getAttributeName() {
			return this.field.getElementName();
		}

		public boolean isField() {
			return true;
		}

		public String getTypeSignature() throws JavaModelException {
			return this.field.getTypeSignature();
		}

		/**
		 * JPTTools needs an adapter so it can work with either an IField
		 * or an IVariableBinding etc.
		 */
		class JPTToolsAdapter implements JPTTools.FieldAdapter {
			public int getModifiers() {
				try {
					return FieldAdapter.this.field.getFlags();
				} catch (JavaModelException ex) {
					JptCorePlugin.log(ex);
					return 0;
				}
			}

		}

	}

	/**
	 * IMethod adapter
	 */
	static class MethodAdapter
		implements Adapter
	{
		final IMethod method;
		static final IMethod[] EMPTY_METHOD_ARRAY = new IMethod[0];

		MethodAdapter(IMethod method) {
			super();
			this.method = method;
		}

		public IMethod getMember() {
			return this.method;
		}

		public boolean isPersistable() {
			return JPTTools.methodIsPersistablePropertyGetter(new JPTToolsAdapter());
		}

		public IAnnotation[] getAnnotations() throws JavaModelException {
			return this.method.getAnnotations();
		}

		public String getAttributeName() {
			return NameTools.convertGetterMethodNameToPropertyName(this.method.getElementName());
		}

		public boolean isField() {
			return false;
		}

		public String getTypeSignature() throws JavaModelException {
			return this.method.getReturnType();
		}

		/**
		 * JPTTools needs an adapter so it can work with either an IMethod
		 * or an IMethodBinding etc.
		 */
		abstract static class AbstractJPTToolsAdapter
			implements JPTTools.SimpleMethodAdapter
		{
			AbstractJPTToolsAdapter() {
				super();
			}

			abstract IMethod getMethod();

			public int getModifiers() {
				try {
					return this.getMethod().getFlags();
				} catch (JavaModelException ex) {
					JptCorePlugin.log(ex);
					return 0;
				}
			}

			public String getReturnTypeErasureName() {
				return convertTypeSignatureToTypeName(this.getReturnTypeSignature());
			}

			private String getReturnTypeSignature() {
				try {
					return this.getMethod().getReturnType();
				} catch (JavaModelException ex) {
					JptCorePlugin.log(ex);
					return null;
				}
			}

			public boolean isConstructor() {
				try {
					return this.getMethod().isConstructor();
				} catch (JavaModelException ex) {
					JptCorePlugin.log(ex);
					return false;
				}
			}

		}

		static class SimpleJPTToolsAdapter
			extends AbstractJPTToolsAdapter
		{
			private final IMethod method;

			SimpleJPTToolsAdapter(IMethod method) {
				super();
				this.method = method;
			}

			@Override
			IMethod getMethod() {
				return this.method;
			}

		}

		class JPTToolsAdapter
			extends AbstractJPTToolsAdapter
			implements JPTTools.MethodAdapter
		{
			JPTToolsAdapter() {
				super();
			}

			@Override
			IMethod getMethod() {
				return MethodAdapter.this.method;
			}

			public String getName() {
				return this.getMethod().getElementName();
			}

			public int getParametersLength() {
				return this.getMethod().getParameterTypes().length;
			}

			public JPTTools.SimpleMethodAdapter getSibling(String name) {
				for (IMethod sibling : this.getSiblings()) {
					if ((sibling.getParameterTypes().length == 0)
							&& sibling.getElementName().equals(name)) {
						return new SimpleJPTToolsAdapter(sibling);
					}
				}
				return null;
			}

			public JPTTools.SimpleMethodAdapter getSibling(String name, String parameterTypeErasureName) {
				for (IMethod sibling : this.getSiblings()) {
					String[] parmTypes = sibling.getParameterTypes();
					if ((parmTypes.length == 1)
							&& sibling.getElementName().equals(name)
							&& convertTypeSignatureToTypeName(parmTypes[0]).equals(parameterTypeErasureName)) {
						return new SimpleJPTToolsAdapter(sibling);
					}
				}
				return null;
			}

			private IMethod[] getSiblings() {
				try {
					return this.getMethod().getDeclaringType().getMethods();
				} catch (JavaModelException ex) {
					JptCorePlugin.log(ex);
					return EMPTY_METHOD_ARRAY;
				}
			}

		}

	}

}
