/*******************************************************************************
 * Copyright (c) 2000, 2016 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *     Stephan Herrmann - Contribution for
 *								Bug 429813 - [1.8][dom ast] IMethodBinding#getJavaElement() should return IMethod for lambda
 *								Bug 466308 - [hovering] Javadoc header for parameter is wrong with annotation-based null analysis
 *******************************************************************************/

package org.aspectj.org.eclipse.jdt.core.dom;

import org.aspectj.org.eclipse.jdt.core.IJavaElement;
import org.aspectj.org.eclipse.jdt.core.JavaCore;
import org.aspectj.org.eclipse.jdt.core.util.IModifierConstants;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.aspectj.org.eclipse.jdt.internal.compiler.impl.Constant;
import org.aspectj.org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TagBits;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import org.aspectj.org.eclipse.jdt.internal.core.JavaElement;
import org.aspectj.org.eclipse.jdt.internal.core.LocalVariable;
import org.aspectj.org.eclipse.jdt.internal.core.util.Util;

/**
 * Internal implementation of variable bindings.
 */
class VariableBinding implements IVariableBinding {

	private static final int VALID_MODIFIERS = Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE |
		Modifier.STATIC | Modifier.FINAL | Modifier.TRANSIENT | Modifier.VOLATILE;

	private org.aspectj.org.eclipse.jdt.internal.compiler.lookup.VariableBinding binding;
	private ITypeBinding declaringClass;
	private String key;
	private String name;
	private BindingResolver resolver;
	private ITypeBinding type;
	private IAnnotationBinding[] annotations;

	VariableBinding(BindingResolver resolver, org.aspectj.org.eclipse.jdt.internal.compiler.lookup.VariableBinding binding) {
		this.resolver = resolver;
		this.binding = binding;
	}

	@Override
	public IAnnotationBinding[] getAnnotations() {
		if (this.annotations != null) {
			return this.annotations;
		}
		org.aspectj.org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding[] internalAnnotations = this.binding.getAnnotations();
		int length = internalAnnotations == null ? 0 : internalAnnotations.length;
		if (length != 0) {
			IAnnotationBinding[] tempAnnotations = new IAnnotationBinding[length];
			int convertedAnnotationCount = 0;
			for (int i = 0; i < length; i++) {
				org.aspectj.org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding internalAnnotation = internalAnnotations[i];
				final IAnnotationBinding annotationInstance = this.resolver.getAnnotationInstance(internalAnnotation);
				if (annotationInstance == null) {
					continue;
				}
				tempAnnotations[convertedAnnotationCount++] = annotationInstance;
			}
			if (convertedAnnotationCount != length) {
				if (convertedAnnotationCount == 0) {
					return this.annotations = AnnotationBinding.NoAnnotations;
				}
				System.arraycopy(tempAnnotations, 0, (tempAnnotations = new IAnnotationBinding[convertedAnnotationCount]), 0, convertedAnnotationCount);
			}
			return this.annotations = tempAnnotations;
		}
		return this.annotations = AnnotationBinding.NoAnnotations;
	}

	@Override
	public Object getConstantValue() {
		Constant c = this.binding.constant();
		if (c == null || c == Constant.NotAConstant) return null;
		switch (c.typeID()) {
			case TypeIds.T_boolean:
				return Boolean.valueOf(c.booleanValue());
			case TypeIds.T_byte:
				return Byte.valueOf(c.byteValue());
			case TypeIds.T_char:
				return Character.valueOf(c.charValue());
			case TypeIds.T_double:
				return new Double(c.doubleValue());
			case TypeIds.T_float:
				return new Float(c.floatValue());
			case TypeIds.T_int:
				return Integer.valueOf(c.intValue());
			case TypeIds.T_long:
				return Long.valueOf(c.longValue());
			case TypeIds.T_short:
				return Short.valueOf(c.shortValue());
			case TypeIds.T_JavaLangString:
				return c.stringValue();
		}
		return null;
	}

	@Override
	public ITypeBinding getDeclaringClass() {
		if (isField()) {
			if (this.declaringClass == null) {
				FieldBinding fieldBinding = (FieldBinding) this.binding;
				this.declaringClass = this.resolver.getTypeBinding(fieldBinding.declaringClass);
			}
			return this.declaringClass;
		} else {
			return null;
		}
	}

	@Override
	public IMethodBinding getDeclaringMethod() {
		if (!isField()) {
			ASTNode node = this.resolver.findDeclaringNode(this);
			while (true) {
				if (node == null) {
					if (this.binding instanceof LocalVariableBinding) {
						LocalVariableBinding localVariableBinding = (LocalVariableBinding) this.binding;
						org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding enclosingMethod = localVariableBinding.getEnclosingMethod();
						if (enclosingMethod != null)
							return this.resolver.getMethodBinding(enclosingMethod);
					}
					return null;
				}
				switch(node.getNodeType()) {
					case ASTNode.INITIALIZER :
						return null;
					case ASTNode.METHOD_DECLARATION :
						MethodDeclaration methodDeclaration = (MethodDeclaration) node;
						return methodDeclaration.resolveBinding();
					case ASTNode.LAMBDA_EXPRESSION :
						LambdaExpression lambdaExpression = (LambdaExpression) node;
						return lambdaExpression.resolveMethodBinding();
					default:
						node = node.getParent();
				}
			}
		}
		return null;
	}

	@Override
	public IJavaElement getJavaElement() {
		JavaElement element = getUnresolvedJavaElement();
		if (element == null)
			return null;
		return element.resolved(this.binding);
	}

	@Override
	public String getKey() {
		if (this.key == null) {
			this.key = new String(this.binding.computeUniqueKey());
		}
		return this.key;
	}

	@Override
	public int getKind() {
		return IBinding.VARIABLE;
	}

	@Override
	public int getModifiers() {
		if (isField()) {
			return ((FieldBinding) this.binding).getAccessFlags() & VALID_MODIFIERS;
		}
		if (this.binding.isFinal()) {
			return IModifierConstants.ACC_FINAL;
		}
		return Modifier.NONE;
	}

	@Override
	public String getName() {
		if (this.name == null) {
			this.name = new String(this.binding.name);
		}
		return this.name;
	}

	@Override
	public ITypeBinding getType() {
		if (this.type == null) {
			this.type = this.resolver.getTypeBinding(this.binding.type);
		}
		return this.type;
	}

	private JavaElement getUnresolvedJavaElement() {
		if (JavaCore.getPlugin() == null) {
			return null;
		}
		if (isField()) {
			if (this.resolver instanceof DefaultBindingResolver) {
				DefaultBindingResolver defaultBindingResolver = (DefaultBindingResolver) this.resolver;
				if (!defaultBindingResolver.fromJavaProject) return null;
				return Util.getUnresolvedJavaElement(
						(FieldBinding) this.binding,
						defaultBindingResolver.workingCopyOwner,
						defaultBindingResolver.getBindingsToNodesMap());
			}
			return null;
		}
		// local variable
		if (!(this.resolver instanceof DefaultBindingResolver)) return null;
		DefaultBindingResolver defaultBindingResolver = (DefaultBindingResolver) this.resolver;
		if (!defaultBindingResolver.fromJavaProject) return null;
		VariableDeclaration localVar = (VariableDeclaration) defaultBindingResolver.bindingsToAstNodes.get(this);
		if (localVar == null) return null;
		SimpleName localName = localVar.getName();
		int nameStart = localName.getStartPosition();
		int nameLength = localName.getLength();
		int sourceStart;
		int sourceLength;
		int modifiers = 0;
		if (localVar instanceof SingleVariableDeclaration) {
			sourceStart = localVar.getStartPosition();
			sourceLength = localVar.getLength();
			final SingleVariableDeclaration singleVariableDeclaration = (SingleVariableDeclaration) localVar;
			modifiers = singleVariableDeclaration.getModifiers();
		} else {
			ASTNode node = localVar.getParent();
			sourceStart = node.getStartPosition();
			sourceLength = node.getLength();
			VariableDeclarationFragment fragment = (VariableDeclarationFragment) localVar;
			final ASTNode parent = fragment.getParent();
			switch (parent.getNodeType()) {
				case ASTNode.VARIABLE_DECLARATION_EXPRESSION :
					VariableDeclarationExpression expression = (VariableDeclarationExpression) parent;
					modifiers = expression.getModifiers();
					break;
				case ASTNode.VARIABLE_DECLARATION_STATEMENT :
					VariableDeclarationStatement statement = (VariableDeclarationStatement) parent;
					modifiers = statement.getModifiers();
					break;
				case ASTNode.FIELD_DECLARATION :
					FieldDeclaration fieldDeclaration = (FieldDeclaration) parent;
					modifiers = fieldDeclaration.getModifiers();
					break;
			}
		}
		int sourceEnd = sourceStart+sourceLength-1;
		char[] typeSig = this.binding.type.genericTypeSignature();
		JavaElement parent = null;
		IMethodBinding declaringMethod = getDeclaringMethod();
		final LocalVariableBinding localVariableBinding = (LocalVariableBinding) this.binding;
		if (declaringMethod == null) {
			ReferenceContext referenceContext = localVariableBinding.declaringScope.referenceContext();
			if (referenceContext instanceof TypeDeclaration){
				// Local variable is declared inside an initializer
				TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
				JavaElement typeHandle = null;
				typeHandle = Util.getUnresolvedJavaElement(
					typeDeclaration.binding,
					defaultBindingResolver.workingCopyOwner,
					defaultBindingResolver.getBindingsToNodesMap());
				parent = Util.getUnresolvedJavaElement(sourceStart, sourceEnd, typeHandle);
			} else {
				return null;
			}
		} else {
			parent = (JavaElement) declaringMethod.getJavaElement();
		}
		if (parent == null) return null;
		return new LocalVariable(
				parent,
				localName.getIdentifier(),
				sourceStart,
				sourceEnd,
				nameStart,
				nameStart+nameLength-1,
				new String(typeSig),
				localVariableBinding.declaration.annotations,
				modifiers,
				(localVariableBinding.tagBits & TagBits.IsArgument) != 0);
	}

	@Override
	public IVariableBinding getVariableDeclaration() {
		if (isField()) {
			FieldBinding fieldBinding = (FieldBinding) this.binding;
			return this.resolver.getVariableBinding(fieldBinding.original());
		}
		return this;
	}

	@Override
	public int getVariableId() {
		return this.binding.id;
	}

	@Override
	public boolean isParameter() {
		return (this.binding.tagBits & TagBits.IsArgument) != 0;
	}

	@Override
	public boolean isDeprecated() {
		if (isField()) {
			return ((FieldBinding) this.binding).isDeprecated();
		}
		return false;
	}

	@Override
	public boolean isEnumConstant() {
		return (this.binding.modifiers & ClassFileConstants.AccEnum) != 0;
	}

	@Override
	public boolean isEqualTo(IBinding other) {
		if (other == this) {
			// identical binding - equal (key or no key)
			return true;
		}
		if (other == null) {
			// other binding missing
			return false;
		}
		if (!(other instanceof VariableBinding)) {
			return false;
		}
		org.aspectj.org.eclipse.jdt.internal.compiler.lookup.VariableBinding otherBinding = ((VariableBinding) other).binding;
		if (this.binding instanceof FieldBinding) {
			if (otherBinding instanceof FieldBinding) {
				return BindingComparator.isEqual((FieldBinding) this.binding, (FieldBinding) otherBinding);
			} else {
				return false;
			}
		} else {
			if (BindingComparator.isEqual(this.binding, otherBinding)) {
				IMethodBinding declaringMethod = getDeclaringMethod();
				IMethodBinding otherDeclaringMethod = ((VariableBinding) other).getDeclaringMethod();
				if (declaringMethod == null) {
					if (otherDeclaringMethod != null) {
						return false;
					}
					return true;
				}
				return declaringMethod.isEqualTo(otherDeclaringMethod);
			}
			return false;
		}
	}

	@Override
	public boolean isField() {
		return this.binding instanceof FieldBinding;
	}

	@Override
	public boolean isSynthetic() {
		if (isField()) {
			return ((FieldBinding) this.binding).isSynthetic();
		}
		return false;
	}

	@Override
	public boolean isRecovered() {
		return false;
	}

	@Override
	public boolean isEffectivelyFinal() {
		return (!this.binding.isFinal() && this.binding.isEffectivelyFinal());
	}

	/*
	 * For debugging purpose only.
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return this.binding.toString();
	}
}
