/*******************************************************************************
 * Copyright (c) 2000, 2012 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.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
			if(parameterNames != null) {
				for (char[] parameterName : parameterNames) {
					resultLength += parameterName.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;
	}
}
