/*******************************************************************************
 * 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 (int i = 0; i < parameterNames.length; 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;
	}
}
