/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.debug.eval.ast.instructions;


import org.eclipse.jdt.core.compiler.CharOperation;

/**
 * Copy of org.eclipse.jdt.core.Signature. The class is copied here
 * solely for the purpose of commenting out the line:
 *   CharOperation.replace(result, C_DOLLAR, C_DOT);
 * in the method toCharArray(char[]).
 * See Bug 22165
 */
public class RuntimeSignature {
	public static final char C_BOOLEAN = 'Z';
	public static final char C_BYTE = 'B';
	public static final char C_CHAR = 'C';
	public static final char C_DOUBLE = 'D';
	public static final char C_FLOAT = 'F';
	public static final char C_INT = 'I';
	public static final char C_SEMICOLON = ';';
	public static final char C_LONG = 'J';
	public static final char C_SHORT = 'S';
	public static final char C_VOID = 'V';
	public static final char C_DOT = '.';
	public static final char C_DOLLAR = '$';
	public static final char C_ARRAY = '[';
	public static final char C_RESOLVED = 'L';
	public static final char C_UNRESOLVED = 'Q';
	public static final char C_NAME_END = ';';
	public static final char C_PARAM_START = '(';
	public static final char C_PARAM_END = ')';
	public static final String SIG_BOOLEAN = "Z"; //$NON-NLS-1$
	public static final String SIG_BYTE = "B"; //$NON-NLS-1$
	public static final String SIG_CHAR = "C"; //$NON-NLS-1$
	public static final String SIG_DOUBLE = "D"; //$NON-NLS-1$
	public static final String SIG_FLOAT = "F"; //$NON-NLS-1$
	public static final String SIG_INT = "I"; //$NON-NLS-1$
	public static final String SIG_LONG = "J"; //$NON-NLS-1$
	public static final String SIG_SHORT = "S"; //$NON-NLS-1$
	public static final String SIG_VOID = "V"; //$NON-NLS-1$
	private static final char[] NO_CHAR = new char[0];
	private static final char[] BOOLEAN = { 'b', 'o', 'o', 'l', 'e', 'a', 'n' };
	private static final char[] BYTE = { 'b', 'y', 't', 'e' };
	private static final char[] CHAR = { 'c', 'h', 'a', 'r' };
	private static final char[] DOUBLE = { 'd', 'o', 'u', 'b', 'l', 'e' };
	private static final char[] FLOAT = { 'f', 'l', 'o', 'a', 't' };
	private static final char[] INT = { 'i', 'n', 't' };
	private static final char[] LONG = { 'l', 'o', 'n', 'g' };
	private static final char[] SHORT = { 's', 'h', 'o', 'r', 't' };
	private static final char[] VOID = { 'v', 'o', 'i', 'd' };

	public static String toString(String signature)
		throws IllegalArgumentException {
		return new String(toCharArray(signature.toCharArray()));
	}

	public static char[] toCharArray(char[] signature)
		throws IllegalArgumentException {
		try {
			int sigLength = signature.length;

			if (sigLength == 0 || signature[0] == C_PARAM_START) {
				return toCharArray(signature, NO_CHAR, null, true, true);
			}

			// compute result length
			int resultLength = 0;
			int index = -1;
			while (signature[++index] == C_ARRAY) {
				resultLength += 2; // []
			}
			switch (signature[index]) {
				case C_BOOLEAN :
					resultLength += BOOLEAN.length;
					break;
				case C_BYTE :
					resultLength += BYTE.length;
					break;
				case C_CHAR :
					resultLength += CHAR.length;
					break;
				case C_DOUBLE :
					resultLength += DOUBLE.length;
					break;
				case C_FLOAT :
					resultLength += FLOAT.length;
					break;
				case C_INT :
					resultLength += INT.length;
					break;
				case C_LONG :
					resultLength += LONG.length;
					break;
				case C_SHORT :
					resultLength += SHORT.length;
					break;
				case C_VOID :
					resultLength += VOID.length;
					break;
				case C_RESOLVED :
				case C_UNRESOLVED :
					int end =
						CharOperation.indexOf(C_SEMICOLON, signature, index);
					if (end == -1)
						throw new IllegalArgumentException();
					int start = index + 1;
					resultLength += end - start;
					break;
				default :
					throw new IllegalArgumentException();
			}

			char[] result = new char[resultLength];
			copyType(signature, 0, result, 0, true);

			/**
			 * Converts '$' separated type signatures into '.' separated type signature.
			 * NOTE: This assumes that the type signature is an inner type signature.
			 *       This is true in most cases, but someone can define a non-inner type 
			 *       name containing a '$'. However to tell the difference, we would have
			 *       to resolve the signature, which cannot be done at this point.
			 */
//			CharOperation.replace(result, C_DOLLAR, C_DOT);

			return result;
		} catch (ArrayIndexOutOfBoundsException e) {
			throw new IllegalArgumentException();
		}
	}

	public static char[] toCharArray(
		char[] methodSignature,
		char[] methodName,
		char[][] parameterNames,
		boolean fullyQualifyTypeNames,
		boolean includeReturnType) {
		try {
			int firstParen =
				CharOperation.indexOf(C_PARAM_START, methodSignature);
			if (firstParen == -1)
				throw new IllegalArgumentException();

			int sigLength = methodSignature.length;

			// compute result length

			// method signature
			int paramCount = 0;
			int lastParen = -1;
			int resultLength = 0;
			signature : for (int i = firstParen; i < sigLength; i++) {
				switch (methodSignature[i]) {
					case C_ARRAY :
						resultLength += 2; // []
						continue signature;
					case C_BOOLEAN :
						resultLength += BOOLEAN.length;
						break;
					case C_BYTE :
						resultLength += BYTE.length;
						break;
					case C_CHAR :
						resultLength += CHAR.length;
						break;
					case C_DOUBLE :
						resultLength += DOUBLE.length;
						break;
					case C_FLOAT :
						resultLength += FLOAT.length;
						break;
					case C_INT :
						resultLength += INT.length;
						break;
					case C_LONG :
						resultLength += LONG.length;
						break;
					case C_SHORT :
						resultLength += SHORT.length;
						break;
					case C_VOID :
						resultLength += VOID.length;
						break;
					case C_RESOLVED :
					case C_UNRESOLVED :
						int end =
							CharOperation.indexOf(
								C_SEMICOLON,
								methodSignature,
								i);
						if (end == -1)
							throw new IllegalArgumentException();
						int start;
						if (fullyQualifyTypeNames) {
							start = i + 1;
						} else {
							start =
								CharOperation.lastIndexOf(
									C_DOT,
									methodSignature,
									i,
									end)
									+ 1;
							if (start == 0)
								start = i + 1;
						}
						resultLength += end - start;
						i = end;
						break;
					case C_PARAM_START :
						// add space for "("
						resultLength++;
						continue signature;
					case C_PARAM_END :
						lastParen = i;
						if (includeReturnType) {
							if (paramCount > 0) {
								// remove space for ", " that was added with last parameter and remove space that is going to be added for ", " after return type 
								// and add space for ") "
								resultLength -= 2;
							} //else
							// remove space that is going to be added for ", " after return type 
							// and add space for ") "
							// -> noop

							// decrement param count because it is going to be added for return type
							paramCount--;
							continue signature;
						} 
						if (paramCount > 0) {
							// remove space for ", " that was added with last parameter and add space for ")"
							resultLength--;
						} else {
							// add space for ")"
							resultLength++;
						}
						break signature;
					default :
						throw new IllegalArgumentException();
				}
				resultLength += 2; // add space for ", "
				paramCount++;
			}

			// parameter names
			int parameterNamesLength =
				parameterNames == null ? 0 : parameterNames.length;
			for (int i = 0; i < parameterNamesLength; i++) {
				resultLength += parameterNames[i].length + 1;
				// parameter name + space
			}

			// selector
			int selectorLength = methodName == null ? 0 : methodName.length;
			resultLength += selectorLength;

			// create resulting char array
			char[] result = new char[resultLength];

			// returned type
			int index = 0;
			if (includeReturnType) {
				long pos =
					copyType(
						methodSignature,
						lastParen + 1,
						result,
						index,
						fullyQualifyTypeNames);
				index = (int) (pos >>> 32);
				result[index++] = ' ';
			}

			// selector
			if (methodName != null) {
				System.arraycopy(methodName, 0, result, index, selectorLength);
				index += selectorLength;
			}

			// parameters
			result[index++] = C_PARAM_START;
			int sigPos = firstParen + 1;
			for (int i = 0; i < paramCount; i++) {
				long pos =
					copyType(
						methodSignature,
						sigPos,
						result,
						index,
						fullyQualifyTypeNames);
				index = (int) (pos >>> 32);
				sigPos = (int) pos;
				if (parameterNames != null) {
					result[index++] = ' ';
					char[] parameterName = parameterNames[i];
					int paramLength = parameterName.length;
					System.arraycopy(
						parameterName,
						0,
						result,
						index,
						paramLength);
					index += paramLength;
				}
				if (i != paramCount - 1) {
					result[index++] = ',';
					result[index++] = ' ';
				}
			}
			if (sigPos >= sigLength) {
				throw new IllegalArgumentException();
				// should be on last paren
			}
			result[index++] = C_PARAM_END;

			return result;
		} catch (ArrayIndexOutOfBoundsException e) {
			throw new IllegalArgumentException();
		}
	}

	private static long copyType(
		char[] signature,
		int sigPos,
		char[] dest,
		int index,
		boolean fullyQualifyTypeNames) {
		int arrayCount = 0;
		loop : while (true) {
			switch (signature[sigPos++]) {
				case C_ARRAY :
					arrayCount++;
					break;
				case C_BOOLEAN :
					int length = BOOLEAN.length;
					System.arraycopy(BOOLEAN, 0, dest, index, length);
					index += length;
					break loop;
				case C_BYTE :
					length = BYTE.length;
					System.arraycopy(BYTE, 0, dest, index, length);
					index += length;
					break loop;
				case C_CHAR :
					length = CHAR.length;
					System.arraycopy(CHAR, 0, dest, index, length);
					index += length;
					break loop;
				case C_DOUBLE :
					length = DOUBLE.length;
					System.arraycopy(DOUBLE, 0, dest, index, length);
					index += length;
					break loop;
				case C_FLOAT :
					length = FLOAT.length;
					System.arraycopy(FLOAT, 0, dest, index, length);
					index += length;
					break loop;
				case C_INT :
					length = INT.length;
					System.arraycopy(INT, 0, dest, index, length);
					index += length;
					break loop;
				case C_LONG :
					length = LONG.length;
					System.arraycopy(LONG, 0, dest, index, length);
					index += length;
					break loop;
				case C_SHORT :
					length = SHORT.length;
					System.arraycopy(SHORT, 0, dest, index, length);
					index += length;
					break loop;
				case C_VOID :
					length = VOID.length;
					System.arraycopy(VOID, 0, dest, index, length);
					index += length;
					break loop;
				case C_RESOLVED :
				case C_UNRESOLVED :
					int end =
						CharOperation.indexOf(C_SEMICOLON, signature, sigPos);
					if (end == -1)
						throw new IllegalArgumentException();
					int start;
					if (fullyQualifyTypeNames) {
						start = sigPos;
					} else {
						start =
							CharOperation.lastIndexOf(
								C_DOT,
								signature,
								sigPos,
								end)
								+ 1;
						if (start == 0)
							start = sigPos;
					}
					length = end - start;
					System.arraycopy(signature, start, dest, index, length);
					sigPos = end + 1;
					index += length;
					break loop;
			}
		}
		while (arrayCount-- > 0) {
			dest[index++] = '[';
			dest[index++] = ']';
		}
		return (((long) index) << 32) + sigPos;
	}
}
