/*******************************************************************************
 * Copyright (c) 2000, 2017 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;

import java.util.Arrays;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.Annotation;

/**
 * Represents JSR 175 Annotation instances in the type-system.
 */
public class AnnotationBinding {
	// do not access directly - use getters instead (UnresolvedAnnotationBinding
	// resolves types for type and pair contents just in time)
	ReferenceBinding type;
	ElementValuePair[] pairs;

/**
 * Add the standard annotations encoded in the tag bits to the recorded annotations.
 *
 * @param recordedAnnotations existing annotations already created
 * @param annotationTagBits
 * @param env
 * @return the combined list of annotations
 */
public static AnnotationBinding[] addStandardAnnotations(AnnotationBinding[] recordedAnnotations, long annotationTagBits, LookupEnvironment env) {
	// NOTE: expect annotations to be requested just once so there is no need to store the standard annotations
	// and all of the standard annotations created by this method are fully resolved since the sender is expected to use them immediately
	if ((annotationTagBits & TagBits.AllStandardAnnotationsMask) == 0) {
		return recordedAnnotations;
	}
	boolean haveDeprecated = false;
	for (AnnotationBinding annotationBinding : recordedAnnotations) {
		if (annotationBinding.getAnnotationType().id == TypeIds.T_JavaLangDeprecated) {
			haveDeprecated = true;
			break;
		}
	}
	int count = 0;
	if ((annotationTagBits & TagBits.AnnotationTargetMASK) != 0)
		count++;
	if ((annotationTagBits & TagBits.AnnotationRetentionMASK) != 0)
		count++;
	if (!haveDeprecated && (annotationTagBits & TagBits.AnnotationDeprecated) != 0)
		count++;
	if ((annotationTagBits & TagBits.AnnotationDocumented) != 0)
		count++;
	if ((annotationTagBits & TagBits.AnnotationInherited) != 0)
		count++;
	if ((annotationTagBits & TagBits.AnnotationOverride) != 0)
		count++;
	if ((annotationTagBits & TagBits.AnnotationSuppressWarnings) != 0)
		count++;
	if ((annotationTagBits & TagBits.AnnotationPolymorphicSignature) != 0)
		count++;
	if ((annotationTagBits & TagBits.AnnotationSafeVarargs) != 0)
		count++;
	if (count == 0) {
		// this is possible if bits were set for null annotations
		return recordedAnnotations;
	}

	int index = recordedAnnotations.length;
	AnnotationBinding[] result = new AnnotationBinding[index + count];
	System.arraycopy(recordedAnnotations, 0, result, 0, index);
	if ((annotationTagBits & TagBits.AnnotationTargetMASK) != 0)
		result[index++] = buildTargetAnnotation(annotationTagBits, env);
	if ((annotationTagBits & TagBits.AnnotationRetentionMASK) != 0)
		result[index++] = buildRetentionAnnotation(annotationTagBits, env);
	if (!haveDeprecated && (annotationTagBits & TagBits.AnnotationDeprecated) != 0)
		result[index++] = buildMarkerAnnotation(TypeConstants.JAVA_LANG_DEPRECATED, env.javaBaseModule(), env);
	if ((annotationTagBits & TagBits.AnnotationDocumented) != 0)
		result[index++] = buildMarkerAnnotation(TypeConstants.JAVA_LANG_ANNOTATION_DOCUMENTED, env.javaBaseModule(), env);
	if ((annotationTagBits & TagBits.AnnotationInherited) != 0)
		result[index++] = buildMarkerAnnotation(TypeConstants.JAVA_LANG_ANNOTATION_INHERITED, env.javaBaseModule(), env);
	if ((annotationTagBits & TagBits.AnnotationOverride) != 0)
		result[index++] = buildMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, env.javaBaseModule(), env);
	if ((annotationTagBits & TagBits.AnnotationSuppressWarnings) != 0)
		result[index++] = buildMarkerAnnotation(TypeConstants.JAVA_LANG_SUPPRESSWARNINGS, env.javaBaseModule(), env);
	if ((annotationTagBits & TagBits.AnnotationPolymorphicSignature) != 0)
		result[index++] = buildMarkerAnnotationForMemberType(TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_$_POLYMORPHICSIGNATURE, env.javaBaseModule(), env);
	if ((annotationTagBits & TagBits.AnnotationSafeVarargs) != 0)
		result[index++] = buildMarkerAnnotation(TypeConstants.JAVA_LANG_SAFEVARARGS, env.javaBaseModule(), env);
	return result;
}

private static AnnotationBinding buildMarkerAnnotationForMemberType(char[][] compoundName, ModuleBinding module, LookupEnvironment env) {
	ReferenceBinding type = env.getResolvedType(compoundName, module, null);
	// since this is a member type name using '$' the return binding is a
	// problem reference binding with reason ProblemReasons.InternalNameProvided
	if (!type.isValidBinding()) {
		type = ((ProblemReferenceBinding) type).closestMatch;
	}
	return env.createAnnotation(type, Binding.NO_ELEMENT_VALUE_PAIRS);
}

private static AnnotationBinding buildMarkerAnnotation(char[][] compoundName, ModuleBinding module, LookupEnvironment env) {
	ReferenceBinding type = env.getResolvedType(compoundName, module, null);
	return env.createAnnotation(type, Binding.NO_ELEMENT_VALUE_PAIRS);
}

private static AnnotationBinding buildRetentionAnnotation(long bits, LookupEnvironment env) {
	ReferenceBinding retentionPolicy =
		env.getResolvedJavaBaseType(TypeConstants.JAVA_LANG_ANNOTATION_RETENTIONPOLICY,
			null);
	Object value = null;
	if ((bits & TagBits.AnnotationRuntimeRetention) == TagBits.AnnotationRuntimeRetention) {
		value = retentionPolicy.getField(TypeConstants.UPPER_RUNTIME, true);
	} else if ((bits & TagBits.AnnotationClassRetention) != 0) {
		value = retentionPolicy.getField(TypeConstants.UPPER_CLASS, true);
	} else if ((bits & TagBits.AnnotationSourceRetention) != 0) {
		value = retentionPolicy.getField(TypeConstants.UPPER_SOURCE, true);
	}
	return env.createAnnotation(
		env.getResolvedJavaBaseType(TypeConstants.JAVA_LANG_ANNOTATION_RETENTION, null),
		new ElementValuePair[] {
			new ElementValuePair(TypeConstants.VALUE, value, null)
		});
}

private static AnnotationBinding buildTargetAnnotation(long bits, LookupEnvironment env) {
	ReferenceBinding target = env.getResolvedJavaBaseType(TypeConstants.JAVA_LANG_ANNOTATION_TARGET, null);
	if ((bits & TagBits.AnnotationTarget) != 0)
		return new AnnotationBinding(target, Binding.NO_ELEMENT_VALUE_PAIRS);

	int arraysize = 0;
	if ((bits & TagBits.AnnotationForAnnotationType) != 0)
		arraysize++;
	if ((bits & TagBits.AnnotationForConstructor) != 0)
		arraysize++;
	if ((bits & TagBits.AnnotationForField) != 0)
		arraysize++;
	if ((bits & TagBits.AnnotationForLocalVariable) != 0)
		arraysize++;
	if ((bits & TagBits.AnnotationForMethod) != 0)
		arraysize++;
	if ((bits & TagBits.AnnotationForPackage) != 0)
		arraysize++;
	if ((bits & TagBits.AnnotationForParameter) != 0)
		arraysize++;
	if ((bits & TagBits.AnnotationForType) != 0)
		arraysize++;
	if ((bits & TagBits.AnnotationForTypeUse) != 0)
		arraysize++;
	if ((bits & TagBits.AnnotationForTypeParameter) != 0)
		arraysize++;
	if ((bits & TagBits.AnnotationForModule) != 0)
		arraysize++;
	
	Object[] value = new Object[arraysize];
	if (arraysize > 0) {
		ReferenceBinding elementType = env.getResolvedType(TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE, null);
		int index = 0;
		if ((bits & TagBits.AnnotationForTypeUse) != 0)
			value[index++] = elementType.getField(TypeConstants.TYPE_USE_TARGET, true);
		if ((bits & TagBits.AnnotationForAnnotationType) != 0)
			value[index++] = elementType.getField(TypeConstants.UPPER_ANNOTATION_TYPE, true);
		if ((bits & TagBits.AnnotationForConstructor) != 0)
			value[index++] = elementType.getField(TypeConstants.UPPER_CONSTRUCTOR, true);
		if ((bits & TagBits.AnnotationForField) != 0)
			value[index++] = elementType.getField(TypeConstants.UPPER_FIELD, true);
		if ((bits & TagBits.AnnotationForMethod) != 0)
			value[index++] = elementType.getField(TypeConstants.UPPER_METHOD, true);
		if ((bits & TagBits.AnnotationForPackage) != 0)
			value[index++] = elementType.getField(TypeConstants.UPPER_PACKAGE, true);
		if ((bits & TagBits.AnnotationForParameter) != 0)
			value[index++] = elementType.getField(TypeConstants.UPPER_PARAMETER, true);
		if ((bits & TagBits.AnnotationForTypeParameter) != 0)
			value[index++] = elementType.getField(TypeConstants.TYPE_PARAMETER_TARGET, true);
		if ((bits & TagBits.AnnotationForType) != 0)
			value[index++] = elementType.getField(TypeConstants.TYPE, true);
		if ((bits & TagBits.AnnotationForLocalVariable) != 0)
			value[index++] = elementType.getField(TypeConstants.UPPER_LOCAL_VARIABLE, true);
	}
	return env.createAnnotation(
			target,
			new ElementValuePair[] {
				new ElementValuePair(TypeConstants.VALUE, value, null)
			});
}

public AnnotationBinding(ReferenceBinding type, ElementValuePair[] pairs) {
	this.type = type;
	this.pairs = pairs;
}

AnnotationBinding(Annotation astAnnotation) {
	this((ReferenceBinding) astAnnotation.resolvedType, astAnnotation.computeElementValuePairs());
}

/*
 * Computes a key that uniquely identifies this binding, using the given recipient's unique key.
 * recipientKey @ typeKey
 * @MyAnnot void bar() --> Lp/X;.bar()V@Lp/MyAnnot;
 */
public char[] computeUniqueKey(char[] recipientKey) {
	char[] typeKey = this.type.computeUniqueKey(false);
	int recipientKeyLength = recipientKey.length;
	char[] uniqueKey = new char[recipientKeyLength+1+typeKey.length];
	System.arraycopy(recipientKey, 0, uniqueKey, 0, recipientKeyLength);
	uniqueKey[recipientKeyLength] = '@';
	System.arraycopy(typeKey, 0, uniqueKey, recipientKeyLength+1, typeKey.length);
	return uniqueKey;
}

public ReferenceBinding getAnnotationType() {
	return this.type;
}

public void resolve() {
	// Nothing to do, this is already resolved.
}

public ElementValuePair[] getElementValuePairs() {
	return this.pairs;
}

public static void setMethodBindings(ReferenceBinding type, ElementValuePair[] pairs) {
	// set the method bindings of each element value pair
	for (int i = pairs.length; --i >= 0;) {
		ElementValuePair pair = pairs[i];
		MethodBinding[] methods = type.getMethods(pair.getName());
		// there should be exactly one since the type is an annotation type.
		if (methods != null && methods.length == 1)
			pair.setMethodBinding(methods[0]);
	}
}

@Override
public String toString() {
	StringBuffer buffer = new StringBuffer(5);
	buffer.append('@').append(this.type.sourceName);
	if (this.pairs != null && this.pairs.length > 0) {
		buffer.append('(');
		if (this.pairs.length == 1 && CharOperation.equals(this.pairs[0].getName(), TypeConstants.VALUE)) {
			buffer.append(this.pairs[0].value); 
		} else {
			for (int i = 0, max = this.pairs.length; i < max; i++) {
				if (i > 0) buffer.append(", "); //$NON-NLS-1$
				buffer.append(this.pairs[i]);
			}
		}
		buffer.append(')');
	}
	return buffer.toString();
}

@Override
public int hashCode() {
	int result = 17;
	int c = this.getAnnotationType().hashCode();
	result = 31 * result + c;
	c =  Arrays.hashCode(this.getElementValuePairs());
	result = 31 * result + c;
	return result;
}
@Override
public boolean equals(Object object) {
	if (this == object)
		return true;
	if (!(object instanceof AnnotationBinding))
		return false;

	AnnotationBinding that = (AnnotationBinding) object;
	if (this.getAnnotationType() != that.getAnnotationType()) //$IDENTITY-COMPARISON$
		return false;

	final ElementValuePair[] thisElementValuePairs = this.getElementValuePairs();
	final ElementValuePair[] thatElementValuePairs = that.getElementValuePairs();
	final int length = thisElementValuePairs.length;
	if (length != thatElementValuePairs.length) 
		return false;
	loop: for (int i = 0; i < length; i++) {
		ElementValuePair thisPair = thisElementValuePairs[i];
		for (int j = 0; j < length; j++) {
			ElementValuePair thatPair = thatElementValuePairs[j];
			if (thisPair.binding == thatPair.binding) {
				if (thisPair.value == null) {
					if (thatPair.value == null) {
						continue loop;
					}
					return false;
				} else {
					if (thatPair.value == null) return false;
					if (thatPair.value instanceof Object[] && thisPair.value instanceof Object[]) {
						if (!Arrays.equals((Object[]) thisPair.value, (Object[]) thatPair.value)) {
							return false;
						}
					} else if (!thatPair.value.equals(thisPair.value)) {
						return false;
					}
				}
				continue loop;
			}
		}
		return false;
	}
	return true;
}
}
