/*******************************************************************************
 * Copyright (c) 2009, 2010 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.jpa2.resource.java.Access2_0Annotation;
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.ClassName;
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
	Iterator<String> validAnnotationNames() {
		return this.getAnnotationProvider().attributeAnnotationNames();
	}
	
	@Override
	Annotation buildAnnotation(IAnnotation jdtAnnotation) {
		return this.getAnnotationProvider().buildAttributeAnnotation(this, jdtAnnotation);
	}
	
	Annotation buildNullAnnotation_(String annotationName) {
		return this.getAnnotationProvider().buildNullAttributeAnnotation(this, annotationName);
	}
	
	
	// ********** JavaResourcePersistentAttribute implementation **********
	
	public String getName() {
		return this.getAdapter().getAttributeName();
	}
	
	@Override
	public Annotation buildNullAnnotation(String annotationName) {
		return (annotationName == null) ? null : this.buildNullAnnotation_(annotationName);
	}
	
	public boolean isField() {
		return this.getAdapter().isField();
	}

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

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

	public AccessType getSpecifiedAccess() {
		Access2_0Annotation accessAnnotation = (Access2_0Annotation) this.getAnnotation(Access2_0Annotation.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) && ClassName.isVariablePrimitive(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_LIST);
	}

	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_LIST);
	}

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

		}

	}

}
