/*******************************************************************************
 * 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
 *     Holger Schill - Bug 455199 - [debug] Debugging doesn't work properly when inner classes are used
 *******************************************************************************/
package org.eclipse.jdt.internal.debug.eval.ast.engine;

import java.util.Iterator;
import java.util.List;

import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.debug.core.IJavaReferenceType;
import org.eclipse.jdt.internal.debug.core.model.JDIReferenceType;

import com.sun.jdi.ClassNotLoadedException;
import com.sun.jdi.ClassNotPreparedException;
import com.sun.jdi.ClassType;
import com.sun.jdi.Field;
import com.sun.jdi.InterfaceType;
import com.sun.jdi.Method;
import com.sun.jdi.ReferenceType;
import com.sun.jdi.Type;

public class BinaryBasedSourceGenerator {

	private static final String RUN_METHOD_NAME = "___run"; //$NON-NLS-1$
	private static final String EVAL_METHOD_NAME = "___eval"; //$NON-NLS-1$
	private static final String ANONYMOUS_CLASS_NAME = "___EvalClass"; //$NON-NLS-1$

	private String[] fLocalVariableTypeNames;

	private String[] fLocalVariableNames;

	private boolean fIsInStaticMethod;

	private StringBuilder fSource;

	private int fRunMethodStartOffset;
	private int fRunMethodLength;
	private int fCodeSnippetPosition;

	private String fCompilationUnitName;

	/**
	 * Level of source code to generate (major, minor). For example 1 and 4
	 * indicates 1.4.
	 */
	private int fSourceMajorLevel;
	private int fSourceMinorLevel;

	public BinaryBasedSourceGenerator(String[] localTypesNames,
			String[] localVariables, boolean isInStaticMethod,
			String sourceLevel) {
		fLocalVariableTypeNames = localTypesNames;
		fLocalVariableNames = localVariables;
		fIsInStaticMethod = isInStaticMethod;
		int index = sourceLevel.indexOf('.');
		String num;
		if (index != -1) {
			num = sourceLevel.substring(0, index);
		} else {
			num = sourceLevel;
		}
		fSourceMajorLevel = Integer.valueOf(num).intValue();
		if (index != -1) {
			num = sourceLevel.substring(index + 1);
			fSourceMinorLevel = Integer.valueOf(num).intValue();
		} else {
			fSourceMinorLevel = 0;
		}
	}

	/**
	 * Build source for an object value (instance context)
	 */
	public void buildSource(JDIReferenceType referenceType) {
		ReferenceType reference = (ReferenceType) referenceType
				.getUnderlyingType();
		fSource = buildTypeDeclaration(reference, buildRunMethod(reference),
				null);
	}

	/**
	 * Build source for a class type (static context)
	 */
	public void buildSourceStatic(IJavaReferenceType type) {
		Type underlyingType = ((JDIReferenceType) type).getUnderlyingType();
		if (!(underlyingType instanceof ReferenceType)) {
			return;
		}
		ReferenceType refType = (ReferenceType) underlyingType;
		fSource = buildTypeDeclaration(refType, buildRunMethod(refType), null,
				false);
		String packageName = getPackageName(refType.name());
		if (packageName != null) {
			fSource.insert(0, "package " + packageName + ";\n"); //$NON-NLS-1$ //$NON-NLS-2$
			fCodeSnippetPosition += 10 + packageName.length();
		}
		fCompilationUnitName = getSimpleName(refType.name());
	}

	protected String getUniqueMethodName(String methodName, ReferenceType type) {
		List<Method> methods = type.methodsByName(methodName);
		while (!methods.isEmpty()) {
			methodName += '_';
			methods = type.methodsByName(methodName);
		}
		return methodName;
	}

	private StringBuilder buildRunMethod(ReferenceType type) {
		StringBuilder source = new StringBuilder();

		if (isInStaticMethod()) {
			source.append("static "); //$NON-NLS-1$
		}

		source.append("void "); //$NON-NLS-1$
		source.append(getUniqueMethodName(RUN_METHOD_NAME, type));
		source.append('(');
		for (int i = 0, length = fLocalVariableNames.length; i < length; i++) {
			source.append(getDotName(fLocalVariableTypeNames[i]));
			source.append(' ');
			source.append(fLocalVariableNames[i]);
			if (i + 1 < length)
			 {
				source.append(", "); //$NON-NLS-1$
			}
		}
		source.append(") throws Throwable {"); //$NON-NLS-1$
		source.append('\n');
		fCodeSnippetPosition = source.length();
		fRunMethodStartOffset = fCodeSnippetPosition;

		source.append('\n');
		source.append('}').append('\n');
		fRunMethodLength = source.length();
		return source;
	}

	private StringBuilder buildTypeDeclaration(ReferenceType referenceType,
			StringBuilder buffer, String nestedTypeName) {

		Field thisField = null;

		for (Field field : referenceType.visibleFields()) {
			if (field.name().startsWith("this$")) { //$NON-NLS-1$
				thisField = field;
				break;
			}
		}

		StringBuilder source = buildTypeDeclaration(referenceType, buffer,
				nestedTypeName, thisField != null);

		if (thisField == null) {
			String packageName = getPackageName(referenceType.name());
			if (packageName != null) {
				source.insert(0, "package " + packageName + ";\n"); //$NON-NLS-1$ //$NON-NLS-2$
				fCodeSnippetPosition += 10 + packageName.length();
			}
			if (isAnonymousTypeName(referenceType.name())) {
				fCompilationUnitName = ANONYMOUS_CLASS_NAME;
			} else {
				fCompilationUnitName = getSimpleName(referenceType.name());
			}
		} else {
			try {
				return buildTypeDeclaration((ReferenceType) thisField.type(),
						source, referenceType.name());
			} catch (ClassNotLoadedException e) {
			}
		}

		return source;
	}

	private StringBuilder buildTypeDeclaration(ReferenceType referenceType,
			StringBuilder buffer, String nestedTypeName,
			boolean hasEnclosingInstance) {
		StringBuilder source = new StringBuilder();

		String typeName = referenceType.name();

		boolean isAnonymousType = isAnonymousTypeName(typeName);

		if (isAnonymousType) {
			ClassType classType = (ClassType) referenceType;

			List<InterfaceType> interfaceList = classType.interfaces();
			String superClassName = classType.superclass().name();
			if (hasEnclosingInstance) {
				source.append("void "); //$NON-NLS-1$
				source.append(getUniqueMethodName(EVAL_METHOD_NAME,
						referenceType));
				source.append("() {\nnew "); //$NON-NLS-1$
				if (!interfaceList.isEmpty()) {
					source.append(getDotName(interfaceList
							.get(0).name()));
				} else {
					source.append(getDotName(superClassName));
				}
				source.append("()"); //$NON-NLS-1$
			} else {
				source.append("public class ").append(ANONYMOUS_CLASS_NAME).append(" "); //$NON-NLS-1$ //$NON-NLS-2$
				if (!interfaceList.isEmpty()) {
					source.append(" implements ").append(getDotName(interfaceList.get(0).name())); //$NON-NLS-1$
				} else {
					source.append(" extends ").append(getDotName(superClassName)); //$NON-NLS-1$
				}
			}

		} else {
			if (referenceType.isFinal()) {
				source.append("final "); //$NON-NLS-1$
			}

			if (referenceType.isStatic()) {
				source.append("static "); //$NON-NLS-1$
			}

			if (referenceType instanceof ClassType) {
				ClassType classType = (ClassType) referenceType;

				if (classType.isAbstract()) {
					source.append("abstract "); //$NON-NLS-1$
				}

				source.append("class "); //$NON-NLS-1$

				source.append(getSimpleName(typeName)).append(' ');

				String genericSignature = referenceType.genericSignature();
				if (genericSignature != null
						&& isSourceLevelGreaterOrEqual(1, 5)) {
					String[] typeParameters = Signature
							.getTypeParameters(genericSignature);
					if (typeParameters.length > 0) {
						source.append('<');
						source.append(Signature
								.getTypeVariable(typeParameters[0]));
						String[] typeParameterBounds = Signature
								.getTypeParameterBounds(typeParameters[0]);
						source.append(" extends ").append(Signature.toString(typeParameterBounds[0]).replace('/', '.')); //$NON-NLS-1$
						for (int i = 1; i < typeParameterBounds.length; i++) {
							source.append(" & ").append(Signature.toString(typeParameterBounds[i]).replace('/', '.')); //$NON-NLS-1$
						}
						for (int j = 1; j < typeParameters.length; j++) {
							source.append(',')
									.append(Signature
											.getTypeVariable(typeParameters[j]));
							typeParameterBounds = Signature
									.getTypeParameterBounds(typeParameters[j]);
							source.append(" extends ").append(Signature.toString(typeParameterBounds[0]).replace('/', '.')); //$NON-NLS-1$
							for (int i = 1; i < typeParameterBounds.length; i++) {
								source.append(" & ").append(Signature.toString(typeParameterBounds[i]).replace('/', '.')); //$NON-NLS-1$
							}
						}
						source.append("> "); //$NON-NLS-1$
					}
					String[] superClassInterfaces = SignatureExt
							.getTypeSuperClassInterfaces(genericSignature);
					int length = superClassInterfaces.length;
					if (length > 0) {
						source.append("extends ").append(Signature.toString(superClassInterfaces[0]).replace('/', '.')); //$NON-NLS-1$
						if (length > 1) {
							source.append(" implements ").append(Signature.toString(superClassInterfaces[1]).replace('/', '.')); //$NON-NLS-1$
							for (int i = 2; i < length; i++) {
								source.append(',')
										.append(Signature
												.toString(superClassInterfaces[1]));
							}
						}
					}
				} else {

					ClassType superClass = classType.superclass();
					if (superClass != null) {
						source.append("extends ").append(getDotName(superClass.name())).append(' '); //$NON-NLS-1$
					}

					List<InterfaceType> interfaces;
					try {
						interfaces = classType.interfaces();
					} catch (ClassNotPreparedException e) {
						return new StringBuilder();
					}
					if (!interfaces.isEmpty()) {
						source.append("implements "); //$NON-NLS-1$
						Iterator<InterfaceType> iterator = interfaces.iterator();
						InterfaceType interface_ = iterator
								.next();
						source.append(getDotName(interface_.name()));
						while (iterator.hasNext()) {
							source.append(',')
									.append(getDotName(iterator
											.next().name()));
						}
					}
				}
			} else if (referenceType instanceof InterfaceType) {
				if (buffer != null) {
					source.append("abstract class "); //$NON-NLS-1$
					source.append(getSimpleName(typeName)).append("___ implements "); //$NON-NLS-1$
					source.append(typeName.replace('$', '.')).append(" {\n"); //$NON-NLS-1$
					fCodeSnippetPosition += source.length();
					source.append(buffer).append("}\n"); //$NON-NLS-1$
					return source;
				}
				source.append("interface "); //$NON-NLS-1$
				source.append(getSimpleName(typeName));
				}
		}

		source.append(" {\n"); //$NON-NLS-1$

		if (buffer != null && !(referenceType instanceof InterfaceType)) {
			fCodeSnippetPosition += source.length();
			source.append(buffer);
		}

		for (Field field : referenceType.fields()) {
			if (!field.name().startsWith("this$")) { //$NON-NLS-1$
				source.append(buildFieldDeclaration(field));
			}
		}

		for (Method method : referenceType.methods()) {
			if (!method.isConstructor() && !method.isStaticInitializer()
				&& !method.isBridge()) {
				source.append(buildMethodDeclaration(method));
			}
		}

		List<ReferenceType> nestedTypes = referenceType.nestedTypes();
		if (nestedTypeName == null) {
			for (ReferenceType nestedType : nestedTypes) {
				if (isADirectInnerType(typeName, nestedType.name())) {
					source.append(buildTypeDeclaration(nestedType, null, null,
						true));
				}
			}
		} else {
			for (ReferenceType nestedType : nestedTypes) {
				if (!nestedTypeName.equals(nestedType.name())
					&& isADirectInnerType(typeName, nestedType.name())) {
					source.append(buildTypeDeclaration(nestedType, null, null,
						true));
				}
			}
		}

		if (isAnonymousType & hasEnclosingInstance) {
			source.append("};\n"); //$NON-NLS-1$
		}

		source.append("}\n"); //$NON-NLS-1$

		return source;
	}

	private StringBuilder buildFieldDeclaration(Field field) {
		StringBuilder source = new StringBuilder();

		if (field.isFinal()) {
			source.append("final "); //$NON-NLS-1$
		}

		if (field.isStatic()) {
			source.append("static "); //$NON-NLS-1$
		}

		if (field.isPublic()) {
			source.append("public "); //$NON-NLS-1$
		} else if (field.isPrivate()) {
			source.append("private "); //$NON-NLS-1$
		} else if (field.isProtected()) {
			source.append("protected "); //$NON-NLS-1$
		}

		source.append(getDotName(field.typeName())).append(' ')
				.append(field.name()).append(';').append('\n');

		return source;
	}

	private StringBuilder buildMethodDeclaration(Method method) {
		StringBuilder source = new StringBuilder();

		if (method.isFinal()) {
			source.append("final "); //$NON-NLS-1$
		}

		if (method.isStatic()) {
			source.append("static "); //$NON-NLS-1$
		}

		if (method.isNative()) {
			source.append("native "); //$NON-NLS-1$
		} else if (method.isAbstract()) {
			source.append("abstract "); //$NON-NLS-1$
		}

		if (method.isPublic()) {
			source.append("public "); //$NON-NLS-1$
		} else if (method.isPrivate()) {
			source.append("private "); //$NON-NLS-1$
		} else if (method.isProtected()) {
			source.append("protected "); //$NON-NLS-1$
		}

		String genericSignature = method.genericSignature();
		if (genericSignature != null && isSourceLevelGreaterOrEqual(1, 5)) {
			String[] typeParameters = Signature
					.getTypeParameters(genericSignature);
			if (typeParameters.length > 0) {
				source.append('<');
				source.append(Signature.getTypeVariable(typeParameters[0]));
				String[] typeParameterBounds = Signature
						.getTypeParameterBounds(typeParameters[0]);
				source.append(" extends ").append(Signature.toString(typeParameterBounds[0]).replace('/', '.')); //$NON-NLS-1$
				for (int i = 1; i < typeParameterBounds.length; i++) {
					source.append(" & ").append(Signature.toString(typeParameterBounds[i]).replace('/', '.')); //$NON-NLS-1$
				}
				for (int j = 1; j < typeParameters.length; j++) {
					source.append(',').append(
							Signature.getTypeVariable(typeParameters[j]));
					typeParameterBounds = Signature
							.getTypeParameterBounds(typeParameters[j]);
					source.append(" extends ").append(Signature.toString(typeParameterBounds[0]).replace('/', '.')); //$NON-NLS-1$
					for (int i = 1; i < typeParameterBounds.length; i++) {
						source.append(" & ").append(Signature.toString(typeParameterBounds[i]).replace('/', '.')); //$NON-NLS-1$
					}
				}
				source.append("> "); //$NON-NLS-1$
			}

			source.append(
					Signature.toString(
							Signature.getReturnType(genericSignature)).replace(
							'/', '.')).append(' ').append(method.name())
					.append('(');

			String[] parameterTypes = Signature
					.getParameterTypes(genericSignature);
			int i = 0;
			if (parameterTypes.length != 0) {
				source.append(
						Signature.toString(parameterTypes[0]).replace('/', '.'))
						.append(" arg").append(i++); //$NON-NLS-1$
				if (method.isVarArgs()) {
					for (int j = 1; j < parameterTypes.length - 1; j++) {
						source.append(',')
								.append(Signature.toString(parameterTypes[j])
										.replace('/', '.'))
								.append(" arg").append(i++); //$NON-NLS-1$
					}
					String typeName = Signature.toString(
							parameterTypes[parameterTypes.length - 1]).replace(
							'/', '.');
					source.append(',')
							.append(typeName.substring(0, typeName.length() - 2))
							.append("...").append(" arg").append(i++); //$NON-NLS-1$ //$NON-NLS-2$
				} else {
					for (int j = 1; j < parameterTypes.length; j++) {
						source.append(',')
								.append(Signature.toString(parameterTypes[j])
										.replace('/', '.'))
								.append(" arg").append(i++); //$NON-NLS-1$
					}
				}
			}
			source.append(')');
		} else {
			source.append(getDotName(method.returnTypeName())).append(' ')
					.append(method.name()).append('(');

			List<String> arguments = method.argumentTypeNames();
			int i = 0;
			if (!arguments.isEmpty()) {
				Iterator<String> iterator = arguments.iterator();
				source.append(getDotName(iterator.next()))
						.append(" arg").append(i++); //$NON-NLS-1$
				if (method.isVarArgs()) {
					while (iterator.hasNext()) {
						source.append(',');
						String argName = getDotName(iterator.next());
						if (!iterator.hasNext()) {
							source.append(
									argName.substring(0, argName.length() - 2))
									.append("..."); //$NON-NLS-1$
						} else {
							source.append(argName);
						}
						source.append(" arg").append(i++); //$NON-NLS-1$
					}
				} else {
					while (iterator.hasNext()) {
						source.append(',')
								.append(getDotName(iterator.next()))
								.append(" arg").append(i++); //$NON-NLS-1$
					}
				}
			}
			source.append(')');
		}

		if (method.isAbstract() || method.isNative()) {
			// No body for abstract and native methods
			source.append(";\n"); //$NON-NLS-1$
		} else {
			source.append('{').append('\n');
			source.append(getReturnStatement(method.returnTypeName()));
			source.append('}').append('\n');
		}

		return source;
	}

	private String getReturnStatement(String returnTypeName) {
		String typeName = getSimpleName(returnTypeName);
		if (typeName.charAt(typeName.length() - 1) == ']') {
			return "return null;\n"; //$NON-NLS-1$
		}
		switch (typeName.charAt(0)) {
		case 'v':
			return ""; //$NON-NLS-1$
		case 'b':
			if (typeName.length() >= 1 && typeName.charAt(1) == 'o') {
				return "return false;\n"; //$NON-NLS-1$
			}
		case 's':
		case 'c':
		case 'i':
		case 'l':
		case 'd':
		case 'f':
			return "return 0;\n"; //$NON-NLS-1$
		default:
			return "return null;\n"; //$NON-NLS-1$
		}
	}

	private String getDotName(String typeName) {
		return typeName.replace('$', '.');
	}

	private boolean isAnonymousTypeName(String typeName) {
		char char0 = getSimpleName(typeName).charAt(0);
		return '0' <= char0 && char0 <= '9';
	}

	private String getSimpleName(String qualifiedName) {
		int pos = qualifiedName.lastIndexOf('$');
		if (pos == -1) {
			pos = qualifiedName.lastIndexOf('.');
		}
		return ((pos == -1) ? qualifiedName : qualifiedName.substring(pos + 1));
	}

	private String getPackageName(String qualifiedName) {
		int pos = qualifiedName.lastIndexOf('.');
		return ((pos == -1) ? null : qualifiedName.substring(0, pos));
	}

	private boolean isADirectInnerType(String typeName, String nestedTypeName) {
		String end = nestedTypeName.substring(typeName.length() + 1);
		return end.indexOf('$') == -1;
	}

	private boolean isInStaticMethod() {
		return fIsInStaticMethod;
	}

	public StringBuilder getSource() {
		return fSource;
	}

	public int getCodeSnippetPosition() {
		return fCodeSnippetPosition;
	}

	public String getCompilationUnitName() {
		return fCompilationUnitName;
	}

	public int getSnippetStart() {
		return fCodeSnippetPosition - 2;
	}

	public int getRunMethodStart() {
		return fCodeSnippetPosition - fRunMethodStartOffset;
	}

	public int getRunMethodLength() {
		return fRunMethodLength;
	}

	/**
	 * Returns whether the source to be generated is greater than or equal to
	 * the given source level.
	 *
	 * @param major
	 *            major level - e.g. 1 from 1.4
	 * @param minor
	 *            minor level - e.g. 4 from 1.4
	 * @return
	 */
	public boolean isSourceLevelGreaterOrEqual(int major, int minor) {
		return (fSourceMajorLevel > major)
				|| (fSourceMajorLevel == major && fSourceMinorLevel >= minor);
	}
}
