/*******************************************************************************
 * Copyright (c) 2009 Mia-Software and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *    Sebastien Minguet (Mia-Software) - initial API and implementation
 *    Frederic Madiot (Mia-Software) - initial API and implementation
 *    Fabien Giquel (Mia-Software) - initial API and implementation
 *    Gabriel Barbier (Mia-Software) - initial API and implementation
 *    Erwan Breton (Sodifrance) - initial API and implementation
 *    Romain Dervaux (Mia-Software) - initial API and implementation
 *******************************************************************************/

package org.eclipse.modisco.java.discoverer.internal.io.java.binding;

import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.ArrayType;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.ConstructorInvocation;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.IPackageBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.ParameterizedType;
import org.eclipse.jdt.core.dom.PrimitiveType;
import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
import org.eclipse.jdt.core.dom.WildcardType;
import org.eclipse.modisco.infra.common.core.logging.MoDiscoLogger;
import org.eclipse.modisco.java.discoverer.internal.JavaActivator;
import org.eclipse.modisco.java.discoverer.internal.Messages;

/**
 * A factory which uses the JDT Binding API to build MoDisco {@link Binding}s.
 *
 * @see IBinding
 * @see ASTParser#setResolveBindings(boolean)
 */
public final class JDTDelegateBindingFactory implements IBindingFactory {
	private boolean logJDTBindingsIssues = false;

	/**
	 * The unique instance of this factory.
	 */
	private static IBindingFactory instance = new JDTDelegateBindingFactory();

	/**
	 * Singleton pattern.
	 */
	private JDTDelegateBindingFactory() {
		super();
	}

	/**
	 * Returns the unique instance of this factory.
	 *
	 * @return the instance.
	 */
	public static IBindingFactory getInstance() {
		return JDTDelegateBindingFactory.instance;
	}

	public void setLogJDTBindingsIssues(final boolean newValue) {
		this.logJDTBindingsIssues = newValue;
	}

	public Binding getBindingForName(final Name name) {
		Binding result = getBinding(name.resolveBinding());
		if (result == null) {
			// System.out.println("*** WARNING : binding '" +
			// name.getFullyQualifiedName() + "' unresolved.");
			result = new UnresolvedBinding(name.getFullyQualifiedName());
		}
		return result;
	}

	public Binding getBindingForPrimitiveType(final PrimitiveType type) {
		Binding result = new Binding(type.getPrimitiveTypeCode().toString());
		return result;
	}

	public Binding getBindingForParameterizedType(final ParameterizedType type) {
		Binding result = null;
		ITypeBinding binding = type.resolveBinding();
		if (binding == null) {
			if (this.logJDTBindingsIssues) {
				MoDiscoLogger.logWarning("*** WARNING : binding '" //$NON-NLS-1$
						+ type.toString() + "' unresolved.", JavaActivator //$NON-NLS-1$
						.getDefault());
			}
			result = new UnresolvedBinding(type.toString());
		} else {
			String bindingId = binding.getQualifiedName();
			// bindingId is of kind 'PP.XX<AA, BB, ..>'
			if (bindingId.indexOf('<') > 0) {
				result = new Binding(bindingId);
			} else {
				// wrong jdt 'PP.XX' return in some misc java construct with
				// compile errors (bugzilla 324761)
				result = new UnresolvedBinding(type.toString());
			}
		}
		return result;
	}

	public Binding getBindingForWildCardType(final WildcardType type) {
		Binding result = null;
		ITypeBinding binding = type.resolveBinding();
		if (binding == null) {
			if (this.logJDTBindingsIssues) {
				MoDiscoLogger.logWarning("*** WARNING : binding '" //$NON-NLS-1$
						+ type.toString() + "' unresolved.", JavaActivator //$NON-NLS-1$
						.getDefault());
			}
			result = new UnresolvedBinding(type.toString());
		} else {
			result = new Binding(binding.getQualifiedName());
		}
		return result;
	}

	public Binding getBindingForArrayType(final ArrayType type) {
		Binding result = null;
		ITypeBinding binding = type.resolveBinding();
		if (binding == null) {
			if (this.logJDTBindingsIssues) {
				MoDiscoLogger.logWarning("*** WARNING : binding '" //$NON-NLS-1$
						+ type.toString() + "' unresolved.", JavaActivator //$NON-NLS-1$
						.getDefault());
			}
			result = new UnresolvedBinding(type.toString());
		} else {
			result = new ClassBinding();
			result.setName(binding.getQualifiedName());
		}
		return result;
	}

	public Binding getBindingForClassInstanceCreation(final ClassInstanceCreation constructorCall) {
		Binding result = null;
		IMethodBinding binding = constructorCall.resolveConstructorBinding();
		if (binding == null || binding.getDeclaringClass() == null) {
			if (this.logJDTBindingsIssues) {
				MoDiscoLogger.logWarning("*** WARNING : binding '" //$NON-NLS-1$
						+ constructorCall.toString() + Messages.JDTDelegateBindingFactory_10,
						JavaActivator.getDefault());
			}

			result = new UnresolvedBinding(constructorCall.toString());
		} else {
			result = getMethodBinding(binding);
		}
		return result;
	}

	public Binding getBindingForConstructorInvocation(final ConstructorInvocation constructorCall) {
		Binding result = null;
		IMethodBinding binding = constructorCall.resolveConstructorBinding();
		if (binding == null || binding.getDeclaringClass() == null) {
			if (this.logJDTBindingsIssues) {
				MoDiscoLogger.logWarning("*** WARNING : binding '" //$NON-NLS-1$
						+ constructorCall.toString() + "' unresolved.", //$NON-NLS-1$
						JavaActivator.getDefault());
			}
			result = new UnresolvedBinding(constructorCall.toString());
		} else {
			result = getMethodBinding(binding);
		}
		return result;
	}

	public Binding getBindingForSuperConstructorInvocation(
			final SuperConstructorInvocation constructorCall) {
		Binding result = null;
		IMethodBinding binding = constructorCall.resolveConstructorBinding();
		if (binding == null || binding.getDeclaringClass() == null) {
			// managing misc binding.getName() NPE
			if (this.logJDTBindingsIssues) {
				MoDiscoLogger.logWarning("*** WARNING : binding '" //$NON-NLS-1$
						+ constructorCall.toString() + "' unresolved.", //$NON-NLS-1$
						JavaActivator.getDefault());
			}
			result = new UnresolvedBinding(constructorCall.toString());
		} else {
			result = getMethodBinding(binding);
		}
		return result;
	}

	private Binding getBinding(final IBinding binding) {
		Binding result = null;
		if (binding instanceof IMethodBinding) {
			result = getMethodBinding((IMethodBinding) binding);

		} else if (binding instanceof ITypeBinding) {
			result = getClassBinding((ITypeBinding) binding, false);

		} else if (binding instanceof IPackageBinding) {
			result = getPackageBinding((IPackageBinding) binding);

		} else if (binding instanceof IVariableBinding && ((IVariableBinding) binding).isField()) {
			result = getFieldBinding((IVariableBinding) binding);

		} else if (binding instanceof IVariableBinding && !((IVariableBinding) binding).isField()) {
			result = getVariableBinding((IVariableBinding) binding);
		}
		return result;
	}

	private MethodBinding getMethodBinding(final IMethodBinding methodBinding) {
		/*
		 * in case of generic method, a parameterized method binding
		 * encapsulates real method in a second binding.
		 */
		IMethodBinding binding = methodBinding.getMethodDeclaration();
		MethodBinding result = new MethodBinding();

		result.setName(binding.getName());
		result.setDeclaringClass(getClassBinding(binding.getDeclaringClass(), false));
		result.setConstructor(binding.isConstructor());
		result.setAnnotationMember(binding.isAnnotationMember());
		for (int i = 0; i < binding.getParameterTypes().length; i++) {
			result.getParameters().add(getParameterBinding(binding.getParameterTypes()[i]));
		}
		return result;
	}

	private ParameterBinding getParameterBinding(final ITypeBinding binding) {
		ParameterBinding result = new ParameterBinding();
		result.setDimensions(binding.getDimensions());
		if (binding.isArray()) {
			result.setElementType(getClassBinding(binding.getElementType(), true));
		} else {
			result.setElementType(getClassBinding(binding, true));
		}
		return result;
	}

	private static PackageBinding getPackageBinding(final IPackageBinding binding) {
		PackageBinding result = new PackageBinding();
		result.setName(binding.getName());
		return result;
	}

	private ClassBinding getClassBinding(final ITypeBinding bindingParameter,
			final boolean isParameterBinding) {
		/*
		 * in case of generic type, a parameterized type binding encapsulates
		 * real type in a second binding.
		 */
		ITypeBinding binding = bindingParameter.getTypeDeclaration();
		ClassBinding result = new ClassBinding();

		if (binding.isTypeVariable() && isParameterBinding) {
			/*
			 * we don't want type variables or generic types in parameter
			 * bindings, so we replace it by the erasure
			 *
			 * @see org.eclipse.jdt.core.dom.ITypeBinding#getErasure()
			 */
			if (binding.getErasure() != null) {
				result = getClassBinding(binding.getErasure(), isParameterBinding);
			} else {
				// in some case, it could be null (see bug 328143)
				result.setName(binding.getName());
				result.setTypeVariable(binding.isTypeVariable());
			}

		} else if (binding.isAnonymous()) {
			/*
			 * as anonymous types don't have names, we cannot have a qualified
			 * name hence they suppose a local context, so we rely on the
			 * binding key
			 */
			result.setName(binding.getKey());

		} else {
			result.setName(binding.getName());
			result.setTypeVariable(binding.isTypeVariable());

			result.setInterface(binding.isInterface());
			result.setEnum(binding.isEnum());
			result.setAnnotation(binding.isAnnotation());
			if (binding.getPackage() != null) {
				result.setOwnerPackage(getPackageBinding(binding.getPackage()));
			}
			if (binding.getDeclaringClass() != null) {
				result.setDeclaringClass(getClassBinding(binding.getDeclaringClass(), false));
			}
			ITypeBinding superClass = binding.getSuperclass();
			if (binding.isClass() && superClass != null
					&& !superClass.getQualifiedName().equals("java.lang.Object")) { //$NON-NLS-1$
				result.setSuperClass(getClassBinding(superClass, false));
			}
			/*
			 * annotations can't have explicit superinterfaces we don't save
			 * this information because an annotation don't have superinterfaces
			 * in the model
			 */
			if (!binding.isAnnotation() && binding.getInterfaces() != null) {
				for (ITypeBinding anInterface : binding.getInterfaces()) {
					if (!anInterface.getQualifiedName().equals("java.lang.Object")) { //$NON-NLS-1$
						result.getSuperInterfaces().add(getClassBinding(anInterface, false));
					}
				}
			}
			if (binding.getTypeParameters() != null) {
				for (ITypeBinding typeParameter : binding.getTypeParameters()) {
					result.addTypeParameters(typeParameter.getName());
				}
			}
		}
		return result;
	}

	private FieldBinding getFieldBinding(final IVariableBinding binding) {
		FieldBinding result = new FieldBinding();
		result.setName(binding.getName());
		result.setEnumConstant(binding.isEnumConstant());
		if (binding.getDeclaringClass() != null) {
			result.setDeclaringClass(getClassBinding(binding.getDeclaringClass(), false));
		}
		return result;
	}

	private static VariableBinding getVariableBinding(final IVariableBinding binding) {
		VariableBinding result = new VariableBinding();
		result.setName(String.valueOf(binding.getVariableId()));
		return result;
	}

	public boolean isLocal(final Name name) {
		return isLocalVariable(name) || isLocalMethod(name);
	}

	private static boolean isLocalVariable(final Name name) {
		boolean result = false;
		IBinding binding = name.resolveBinding();
		if (binding != null) {
			result = (binding instanceof IVariableBinding && !((IVariableBinding) binding)
					.isField());
		}
		return result;
	}

	private static boolean isLocalMethod(final Name name) {
		boolean result = false;
		IBinding binding = name.resolveBinding();
		if (binding != null) {
			if (binding instanceof IMethodBinding) {
				ITypeBinding declaringClass = ((IMethodBinding) binding).getDeclaringClass();
				if (declaringClass != null) {
					result = declaringClass.isAnonymous();
				}
			}
		}
		return result;
	}

}
