/*******************************************************************************
 * Copyright (c) 2000, 2011 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
 *******************************************************************************/
package org.eclipse.jdt.internal.core;

import java.util.HashMap;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.Literal;
import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
import org.eclipse.jdt.internal.compiler.ast.UnaryExpression;
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
import org.eclipse.jdt.internal.compiler.parser.RecoveryScanner;
import org.eclipse.jdt.internal.core.util.MementoTokenizer;
import org.eclipse.jdt.internal.core.util.Util;


public class LocalVariable extends SourceRefElement implements ILocalVariable {

	public static final ILocalVariable[] NO_LOCAL_VARIABLES = new ILocalVariable[0];
	
	String name;
	public int declarationSourceStart, declarationSourceEnd;
	public int nameStart, nameEnd;
	String typeSignature;
	public IAnnotation[] annotations;
	private int flags;
	private boolean isParameter;

	public LocalVariable(
			JavaElement parent,
			String name,
			int declarationSourceStart,
			int declarationSourceEnd,
			int nameStart,
			int nameEnd,
			String typeSignature,
			org.eclipse.jdt.internal.compiler.ast.Annotation[] astAnnotations,
			int flags,
			boolean isParameter) {

		super(parent);
		this.name = name;
		this.declarationSourceStart = declarationSourceStart;
		this.declarationSourceEnd = declarationSourceEnd;
		this.nameStart = nameStart;
		this.nameEnd = nameEnd;
		this.typeSignature = typeSignature;
		this.annotations = getAnnotations(astAnnotations);
		this.flags = flags;
		this.isParameter = isParameter;
	}

	protected void closing(Object info) {
		// a local variable has no info
	}

	protected Object createElementInfo() {
		// a local variable has no info
		return null;
	}

	public boolean equals(Object o) {
		if (!(o instanceof LocalVariable)) return false;
		LocalVariable other = (LocalVariable)o;
		return
			this.declarationSourceStart == other.declarationSourceStart
			&& this.declarationSourceEnd == other.declarationSourceEnd
			&& this.nameStart == other.nameStart
			&& this.nameEnd == other.nameEnd
			&& super.equals(o);
	}

	public boolean exists() {
		return this.parent.exists(); // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=46192
	}

	protected void generateInfos(Object info, HashMap newElements, IProgressMonitor pm) {
		// a local variable has no info
	}

	public IAnnotation getAnnotation(String annotationName) {
		for (int i = 0, length = this.annotations.length; i < length; i++) {
			IAnnotation annotation = this.annotations[i];
			if (annotation.getElementName().equals(annotationName))
				return annotation;
		}
		return super.getAnnotation(annotationName);
	}

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

	private IAnnotation[] getAnnotations(org.eclipse.jdt.internal.compiler.ast.Annotation[] astAnnotations) {
		int length;
		if (astAnnotations == null || (length = astAnnotations.length) == 0)
			return Annotation.NO_ANNOTATIONS;
		IAnnotation[] result = new IAnnotation[length];
		for (int i = 0; i < length; i++) {
			result[i] = getAnnotation(astAnnotations[i], this);
		}
		return result;
	}

	private IAnnotation getAnnotation(final org.eclipse.jdt.internal.compiler.ast.Annotation annotation, JavaElement parentElement) {
		final int typeStart = annotation.type.sourceStart();
		final int typeEnd = annotation.type.sourceEnd();
		final int sourceStart = annotation.sourceStart();
		final int sourceEnd = annotation.declarationSourceEnd;
		class LocalVarAnnotation extends Annotation {
			IMemberValuePair[] memberValuePairs;
			public LocalVarAnnotation(JavaElement localVar, String elementName) {
				super(localVar, elementName);
			}
			public IMemberValuePair[] getMemberValuePairs() throws JavaModelException {
				return this.memberValuePairs;
			}
			public ISourceRange getNameRange() throws JavaModelException {
				return new SourceRange(typeStart, typeEnd - typeStart + 1);
			}
			public ISourceRange getSourceRange() throws JavaModelException {
				return new SourceRange(sourceStart, sourceEnd - sourceStart + 1);
			}
			public boolean exists() {
				return this.parent.exists();
			}
		}
		String annotationName = new String(CharOperation.concatWith(annotation.type.getTypeName(), '.'));
		LocalVarAnnotation localVarAnnotation = new LocalVarAnnotation(parentElement, annotationName);
		org.eclipse.jdt.internal.compiler.ast.MemberValuePair[] astMemberValuePairs = annotation.memberValuePairs();
		int length;
		IMemberValuePair[] memberValuePairs;
		if (astMemberValuePairs == null || (length = astMemberValuePairs.length) == 0) {
			memberValuePairs = Annotation.NO_MEMBER_VALUE_PAIRS;
		} else {
			memberValuePairs = new IMemberValuePair[length];
			for (int i = 0; i < length; i++) {
				org.eclipse.jdt.internal.compiler.ast.MemberValuePair astMemberValuePair = astMemberValuePairs[i];
				MemberValuePair memberValuePair = new MemberValuePair(new String(astMemberValuePair.name));
				memberValuePair.value = getAnnotationMemberValue(memberValuePair, astMemberValuePair.value, localVarAnnotation);
				memberValuePairs[i] = memberValuePair;
			}
		}
		localVarAnnotation.memberValuePairs = memberValuePairs;
		return localVarAnnotation;
	}

	/*
	 * Creates the value wrapper from the given expression, and sets the valueKind on the given memberValuePair
	 */
	private Object getAnnotationMemberValue(MemberValuePair memberValuePair, Expression expression, JavaElement parentElement) {
		if (expression instanceof NullLiteral) {
			return null;
		} else if (expression instanceof Literal) {
			((Literal) expression).computeConstant();
			return Util.getAnnotationMemberValue(memberValuePair, expression.constant);
		} else if (expression instanceof org.eclipse.jdt.internal.compiler.ast.Annotation) {
			memberValuePair.valueKind = IMemberValuePair.K_ANNOTATION;
			return getAnnotation((org.eclipse.jdt.internal.compiler.ast.Annotation) expression, parentElement);
		} else if (expression instanceof ClassLiteralAccess) {
			ClassLiteralAccess classLiteral = (ClassLiteralAccess) expression;
			char[] typeName = CharOperation.concatWith(classLiteral.type.getTypeName(), '.');
			memberValuePair.valueKind = IMemberValuePair.K_CLASS;
			return new String(typeName);
		} else if (expression instanceof QualifiedNameReference) {
			char[] qualifiedName = CharOperation.concatWith(((QualifiedNameReference) expression).tokens, '.');
			memberValuePair.valueKind = IMemberValuePair.K_QUALIFIED_NAME;
			return new String(qualifiedName);
		} else if (expression instanceof SingleNameReference) {
			char[] simpleName = ((SingleNameReference) expression).token;
			if (simpleName == RecoveryScanner.FAKE_IDENTIFIER) {
				memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN;
				return null;
			}
			memberValuePair.valueKind = IMemberValuePair.K_SIMPLE_NAME;
			return new String(simpleName);
		} else if (expression instanceof ArrayInitializer) {
			memberValuePair.valueKind = -1; // modified below by the first call to getMemberValue(...)
			Expression[] expressions = ((ArrayInitializer) expression).expressions;
			int length = expressions == null ? 0 : expressions.length;
			Object[] values = new Object[length];
			for (int i = 0; i < length; i++) {
				int previousValueKind = memberValuePair.valueKind;
				Object value = getAnnotationMemberValue(memberValuePair, expressions[i], parentElement);
				if (previousValueKind != -1 && memberValuePair.valueKind != previousValueKind) {
					// values are heterogeneous, value kind is thus unknown
					memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN;
				}
				values[i] = value;
			}
			if (memberValuePair.valueKind == -1)
				memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN;
			return values;
		} else if (expression instanceof UnaryExpression) {			//to deal with negative numerals (see bug - 248312)
			UnaryExpression unaryExpression = (UnaryExpression) expression;
			if ((unaryExpression.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT == OperatorIds.MINUS) {
				if (unaryExpression.expression instanceof Literal) {
					Literal subExpression = (Literal) unaryExpression.expression;
					subExpression.computeConstant();
					return Util.getNegativeAnnotationMemberValue(memberValuePair, subExpression.constant);
				}
			}
			memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN;
			return null;
		} else {
			memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN;
			return null;
		}
	}

	public IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner owner) {
		switch (token.charAt(0)) {
			case JEM_COUNT:
				return getHandleUpdatingCountFromMemento(memento, owner);
		}
		return this;
	}

	/*
	 * @see JavaElement#getHandleMemento(StringBuffer)
	 */
	protected void getHandleMemento(StringBuffer buff) {
		((JavaElement)getParent()).getHandleMemento(buff);
		buff.append(getHandleMementoDelimiter());
		buff.append(this.name);
		buff.append(JEM_COUNT);
		buff.append(this.declarationSourceStart);
		buff.append(JEM_COUNT);
		buff.append(this.declarationSourceEnd);
		buff.append(JEM_COUNT);
		buff.append(this.nameStart);
		buff.append(JEM_COUNT);
		buff.append(this.nameEnd);
		buff.append(JEM_COUNT);
		escapeMementoName(buff, this.typeSignature);
		buff.append(JEM_COUNT);
		buff.append(this.flags);
		buff.append(JEM_COUNT);
		buff.append(this.isParameter);
		if (this.occurrenceCount > 1) {
			buff.append(JEM_COUNT);
			buff.append(this.occurrenceCount);
		}
	}

	protected char getHandleMementoDelimiter() {
		return JavaElement.JEM_LOCALVARIABLE;
	}

	public IResource getCorrespondingResource() {
		return null;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 3.7
	 */
	public IMember getDeclaringMember() {
		return (IMember) this.parent;
	}

	public String getElementName() {
		return this.name;
	}

	public int getElementType() {
		return LOCAL_VARIABLE;
	}

	/**
	 * {@inheritDoc}
	 * @since 3.7
	 */
	public int getFlags() {
		if (this.flags == -1) {
			SourceMapper mapper= getSourceMapper();
			if (mapper != null) {
				try {
					// ensure the class file's buffer is open so that source ranges are computed
					ClassFile classFile = (ClassFile)getClassFile();
					if (classFile != null) {
						classFile.getBuffer();
						return mapper.getFlags(this);
					}
				} catch(JavaModelException e) {
					// ignore
				}
			}
			return 0;
		}
		return this.flags & ExtraCompilerModifiers.AccJustFlag;
	}

	/**
	 * @see IMember#getClassFile()
	 */
	public IClassFile getClassFile() {
		IJavaElement element = getParent();
		while (element instanceof IMember) {
			element= element.getParent();
		}
		if (element instanceof IClassFile) {
			return (IClassFile) element;
		}
		return null;
	}
	/**
	 * {@inheritDoc}
	 * @since 3.7
	 */
	public ISourceRange getNameRange() {
		if (this.nameEnd == -1) {
			SourceMapper mapper= getSourceMapper();
			if (mapper != null) {
				try {
					// ensure the class file's buffer is open so that source ranges are computed
					ClassFile classFile = (ClassFile)getClassFile();
					if (classFile != null) {
						classFile.getBuffer();
						return mapper.getNameRange(this);
					}
				} catch(JavaModelException e) {
					// ignore
				}
			}
			return SourceMapper.UNKNOWN_RANGE;
		}
		return new SourceRange(this.nameStart, this.nameEnd-this.nameStart+1);
	}

	public IPath getPath() {
		return this.parent.getPath();
	}

	public IResource resource() {
		return this.parent.resource();
	}

	/**
	 * @see ISourceReference
	 */
	public String getSource() throws JavaModelException {
		IOpenable openable = this.parent.getOpenableParent();
		IBuffer buffer = openable.getBuffer();
		if (buffer == null) {
			return null;
		}
		ISourceRange range = getSourceRange();
		int offset = range.getOffset();
		int length = range.getLength();
		if (offset == -1 || length == 0 ) {
			return null;
		}
		try {
			return buffer.getText(offset, length);
		} catch(RuntimeException e) {
			return null;
		}
	}

	/**
	 * {@inheritDoc}
	 * @since 3.7
	 */
	public ISourceRange getSourceRange() throws JavaModelException {
		if (this.declarationSourceEnd == -1) {
			SourceMapper mapper= getSourceMapper();
			if (mapper != null) {
				// ensure the class file's buffer is open so that source ranges are computed
				ClassFile classFile = (ClassFile)getClassFile();
				if (classFile != null) {
					classFile.getBuffer();
					return mapper.getSourceRange(this);
				}
			}
			return SourceMapper.UNKNOWN_RANGE;
		}
		return new SourceRange(this.declarationSourceStart, this.declarationSourceEnd-this.declarationSourceStart+1);
	}

	/**
	 * {@inheritDoc}
	 * @since 3.7
	 */
	public ITypeRoot getTypeRoot() {
		return this.getDeclaringMember().getTypeRoot();
	}

	public String getTypeSignature() {
		return this.typeSignature;
	}

	public IResource getUnderlyingResource() throws JavaModelException {
		return this.parent.getUnderlyingResource();
	}

	public int hashCode() {
		return Util.combineHashCodes(this.parent.hashCode(), this.nameStart);
	}
	
	/**
	 * {@inheritDoc}
	 * @since 3.7
	 */
	public boolean isParameter() {
		return this.isParameter;
	}

	public boolean isStructureKnown() throws JavaModelException {
		return true;
	}

	protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
		buffer.append(tabString(tab));
		if (info != NO_INFO) {
			buffer.append(Signature.toString(getTypeSignature()));
			buffer.append(" "); //$NON-NLS-1$
		}
		toStringName(buffer);
	}

}
