/*******************************************************************************
 * Copyright (c) 2000, 2017 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
 *     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 StringBuffer 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 StringBuffer buildRunMethod(ReferenceType type) {
		StringBuffer source = new StringBuffer();

		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 StringBuffer buildTypeDeclaration(ReferenceType referenceType,
			StringBuffer buffer, String nestedTypeName) {

		Field thisField = null;

		List<Field> fields = referenceType.visibleFields();
		for (Iterator<Field> iterator = fields.iterator(); iterator.hasNext();) {
			Field field = iterator.next();
			if (field.name().startsWith("this$")) { //$NON-NLS-1$
				thisField = field;
				break;
			}
		}

		StringBuffer 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 StringBuffer buildTypeDeclaration(ReferenceType referenceType,
			StringBuffer buffer, String nestedTypeName,
			boolean hasEnclosingInstance) {
		StringBuffer source = new StringBuffer();

		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.size() != 0) {
					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.size() != 0) {
					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 StringBuffer();
					}
					if (interfaces.size() != 0) {
						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);
		}

		List<Field> fields = referenceType.fields();
		for (Iterator<Field> iterator = fields.iterator(); iterator.hasNext();) {
			Field field = iterator.next();
			if (!field.name().startsWith("this$")) { //$NON-NLS-1$
				source.append(buildFieldDeclaration(field));
			}
		}

		List<Method> methods = referenceType.methods();
		for (Iterator<Method> iterator = methods.iterator(); iterator.hasNext();) {
			Method method = iterator.next();
			if (!method.isConstructor() && !method.isStaticInitializer()
					&& !method.isBridge()) {
				source.append(buildMethodDeclaration(method));
			}
		}

		List<ReferenceType> nestedTypes = referenceType.nestedTypes();
		if (nestedTypeName == null) {
			for (Iterator<ReferenceType> iterator = nestedTypes.iterator(); iterator.hasNext();) {
				ReferenceType nestedType = iterator.next();
				if (isADirectInnerType(typeName, nestedType.name())) {
					source.append(buildTypeDeclaration(nestedType, null, null,
							true));
				}
			}
		} else {
			for (Iterator<ReferenceType> iterator = nestedTypes.iterator(); iterator.hasNext();) {
				ReferenceType nestedType = iterator.next();
				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 StringBuffer buildFieldDeclaration(Field field) {
		StringBuffer source = new StringBuffer();

		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 StringBuffer buildMethodDeclaration(Method method) {
		StringBuffer source = new StringBuffer();

		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.size() != 0) {
				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 StringBuffer 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);
	}
}
