/*******************************************************************************
 * Copyright (c) 2000, 2005 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.corext.template.java;

import java.util.Arrays;

import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;

/**
 * Utilities for Signature operations.
 * 
 * @see Signature
 * @since 3.1
 */
public final class SignatureUtil {
	
	/**
	 * The signature of the null type. This type does not really exist in the
	 * type system. It represents the bound of type variables that have no lower
	 * bound, for example the parameter type to the <code>add</code> method of
	 * an instance of <code>java.util.List&lt;? extends Number&gt;</code>.
	 * <p>
	 * The only possible value that has that type is <code>null</code>.
	 * </p>
	 * <p>
	 * The representation of the null type is the signature of a type variable
	 * named <code>null</code> ({@value}), which will only work if no such
	 * variable gets declared in the same context.
	 */
	private static final String NULL_TYPE_SIGNATURE= "Tnull;"; //$NON-NLS-1$
	private static final char[] NULL_TYPE_SIGNATURE_ARRAY= NULL_TYPE_SIGNATURE.toCharArray();
	/**
	 * The signature of <code>java.lang.Object</code> ({@value}).
	 */
	private static final String OBJECT_SIGNATURE= "Ljava.lang.Object;"; //$NON-NLS-1$
	private static final char[] OBJECT_SIGNATURE_ARRAY= OBJECT_SIGNATURE.toCharArray();

	private SignatureUtil() {
		// do not instantiate
	}
	
	/**
	 * Returns <code>true</code> if <code>signature</code> is the
	 * signature of the <code>java.lang.Object</code> type.
	 * 
	 * @param signature the signature
	 * @return <code>true</code> if <code>signature</code> is the
	 *         signature of the <code>java.lang.Object</code> type,
	 *         <code>false</code> otherwise
	 */
	public static boolean isJavaLangObject(String signature) {
		return OBJECT_SIGNATURE.equals(signature);
	}
	
	/**
	 * Returns the upper bound of a type signature. Returns the signature of <code>java.lang.Object</code> if
	 * <code>signature</code> is a lower bound (<code>? super T</code>); returns
	 * the signature of the type <code>T</code> of an upper bound (<code>? extends T</code>)
	 * or <code>signature</code> itself if it is not a bound signature.
	 * 
	 * @param signature the signature
	 * @return the upper bound signature of <code>signature</code>
	 */
	public static String getUpperBound(String signature) {
		return String.valueOf(getUpperBound(signature.toCharArray()));
	}

	/**
	 * Returns the upper bound of a type signature. Returns the signature of <code>java.lang.Object</code> if
	 * <code>signature</code> is a lower bound (<code>? super T</code>); returns
	 * the signature of the type <code>T</code> of an upper bound (<code>? extends T</code>)
	 * or <code>signature</code> itself if it is not a bound signature.
	 * 
	 * @param signature the signature
	 * @return the upper bound signature of <code>signature</code>
	 */
	public static char[] getUpperBound(char[] signature) {
		if (signature.length < 1)
			return signature;
		
		if (signature[0] == Signature.C_STAR)
			return OBJECT_SIGNATURE_ARRAY;
		
		int superIndex= indexOf(signature, Signature.C_SUPER);
		if (superIndex == 0)
			return OBJECT_SIGNATURE_ARRAY;
		
		if (superIndex != -1) {
			char afterSuper= signature[superIndex + 1];
			if (afterSuper == Signature.C_STAR) {
				char[] type= new char[signature.length - 1];
				System.arraycopy(signature, 0, type, 0, superIndex);
				type[superIndex]= Signature.C_STAR;
				System.arraycopy(signature, superIndex + 2, type, superIndex + 1, signature.length - superIndex - 2);
				return getUpperBound(type);
			}
				
			if (afterSuper == Signature.C_EXTENDS) {
				int typeEnd= typeEnd(signature, superIndex + 1);
				char[] type= new char[signature.length - (typeEnd - superIndex - 1)];
				System.arraycopy(signature, 0, type, 0, superIndex);
				type[superIndex]= Signature.C_STAR;
				System.arraycopy(signature, typeEnd, type, superIndex + 1, signature.length - typeEnd);
				return getUpperBound(type);
			}
				
		}
		
		if (signature[0] == Signature.C_EXTENDS) {
			char[] type= new char[signature.length - 1];
			System.arraycopy(signature, 1, type, 0, signature.length - 1);
			return type;
		}
		
		return signature;
	}

	/**
	 * Returns the lower bound of a type signature. Returns the null type
	 * signature if <code>signature</code> is a wildcard or upper bound (<code>? extends T</code>);
	 * returns the signature of the type <code>T</code> of a lower bound (<code>? super T</code>)
	 * or <code>signature</code> itself if it is not a bound signature.
	 * 
	 * @param signature the signature
	 * @return the lower bound signature of <code>signature</code>
	 */
	public static String getLowerBound(String signature) {
		return String.valueOf(getLowerBound(signature.toCharArray()));
	}

	/**
	 * Returns the lower bound of a type signature. Returns the null type
	 * signature if <code>signature</code> is a wildcard or upper bound (<code>? extends T</code>);
	 * returns the signature of the type <code>T</code> of a lower bound (<code>? super T</code>)
	 * or <code>signature</code> itself if it is not a bound signature.
	 * 
	 * @param signature the signature
	 * @return the lower bound signature of <code>signature</code>
	 */
	public static char[] getLowerBound(char[] signature) {
		if (signature.length < 1)
			return signature;
		
		if (signature[0] == Signature.C_STAR)
			return NULL_TYPE_SIGNATURE_ARRAY;
		
		int superIndex= indexOf(signature, Signature.C_EXTENDS);
		if (superIndex == 0)
			return NULL_TYPE_SIGNATURE_ARRAY;
		
		if (superIndex != -1) {
			char afterSuper= signature[superIndex + 1];
			if (afterSuper == Signature.C_STAR || afterSuper == Signature.C_EXTENDS)
				// impossible captured type
				return NULL_TYPE_SIGNATURE_ARRAY;
		}
		
		char[][] typeArguments= Signature.getTypeArguments(signature);
		for (int i= 0; i < typeArguments.length; i++)
			if (Arrays.equals(typeArguments[i], NULL_TYPE_SIGNATURE_ARRAY))
				return NULL_TYPE_SIGNATURE_ARRAY;
		
		if (signature[0] == Signature.C_SUPER) {
			char[] type= new char[signature.length - 1];
			System.arraycopy(signature, 1, type, 0, signature.length - 1);
			return type;
		}
		
		return signature;
	}

	private static int indexOf(char[] signature, char ch) {
		for (int i= 0; i < signature.length; i++) {
			if (signature[i] == ch)
				return i;
		}
		return -1;
	}

	/**
	 * Returns the fully qualified type name of the given signature, with any
	 * type parameters and arrays erased.
	 * 
	 * @param signature the signature
	 * @return the fully qualified type name of the signature
	 */
	public static String stripSignatureToFQN(String signature) throws IllegalArgumentException {
		signature= Signature.getTypeErasure(signature);
		signature= Signature.getElementType(signature);
		return Signature.toString(signature);
	}
	
	/**
	 * Returns the qualified signature corresponding to
	 * <code>signature</code>.
	 * 
	 * @param signature the signature to qualify
	 * @param context the type inside which an unqualified type will be
	 *        resolved to find the qualifier, or <code>null</code> if no
	 *        context is available
	 * @return the qualified signature
	 */
	public static String qualifySignature(final String signature, final IType context) {
		if (context == null)
			return signature;
		
		String qualifier= Signature.getSignatureQualifier(signature);
		if (qualifier.length() > 0)
			return signature;

		String elementType= Signature.getElementType(signature);
		String erasure= Signature.getTypeErasure(elementType);
		String simpleName= Signature.getSignatureSimpleName(erasure);
		String genericSimpleName= Signature.getSignatureSimpleName(elementType);
		
		int dim= Signature.getArrayCount(signature);
		
		try {
			String[][] strings= context.resolveType(simpleName);
			if (strings != null && strings.length > 0)
				qualifier= strings[0][0];
		} catch (JavaModelException e) {
			// ignore - not found
		}
		
		if (qualifier.length() == 0)
			return signature;
		
		String qualifiedType= Signature.toQualifiedName(new String[] {qualifier, genericSimpleName});
		String qualifiedSignature= Signature.createTypeSignature(qualifiedType, true);
		String newSignature= Signature.createArraySignature(qualifiedSignature, dim);
		
		return newSignature;
	}
	
	/**
	 * Takes a method signature
	 * <code>[&lt; typeVariableName : formalTypeDecl &gt;] ( paramTypeSig1* ) retTypeSig</code>
	 * and returns it with any parameter signatures filtered through
	 * <code>getLowerBound</code> and the return type filtered through
	 * <code>getUpperBound</code>. Any preceding formal type variable
	 * declarations are removed.
	 * <p>
	 * TODO this is a temporary workaround for
	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=83600
	 * </p>
	 * 
	 * @param signature the method signature to convert
	 * @return the signature with no bounded types
	 */
	public static char[] unboundedSignature(char[] signature) {
		if (signature == null || signature.length < 2)
			return signature;
		
		final boolean BUG_83600= true;
		// XXX the signatures from CompletionRequestor contain a superfluous '+'
		// before type parameters to parameter types
		if (BUG_83600) {
			signature= fix83600(signature);
		}
		
		StringBuffer res= new StringBuffer("("); //$NON-NLS-1$
		char[][] parameters= Signature.getParameterTypes(signature);
		for (int i= 0; i < parameters.length; i++) {
			char[] param= parameters[i];
			res.append(getLowerBound(param));
		}
		res.append(')');
		res.append(getUpperBound(Signature.getReturnType(signature)));
		return res.toString().toCharArray();
	}

	/**
	 * TODO this is a temporary workaround for
	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=83600 and
	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=85293
	 * 
	 * @param signature the method signature to convert
	 * @return the fixed signature
	 */
	public static char[] fix83600(char[] signature) {
		if (signature == null || signature.length < 2)
			return signature;
		
		return Signature.removeCapture(signature);
	}

	private static int typeEnd(char[] signature, int pos) {
		int depth= 0;
		while (pos < signature.length) {
			switch (signature[pos]) {
				case Signature.C_GENERIC_START:
					depth++;
					break;
				case Signature.C_GENERIC_END:
					depth--;
					break;
				case Signature.C_SEMICOLON:
					if (depth == 0)
						return pos + 1;
					break;
			}
			pos++;
		}
		return pos + 1;
	}
}
