/*******************************************************************************
 * Copyright (c) 2000, 2008 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
 *******************************************************************************/
package org.eclipse.jdt.core.tests.eval;

import java.io.File;

import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.eclipse.jdt.core.tests.runtime.LocalVMLauncher;
import org.eclipse.jdt.core.tests.runtime.LocalVirtualMachine;

import org.eclipse.jdt.core.tests.runtime.TargetException;
import org.eclipse.jdt.core.tests.runtime.TargetInterface;
import org.eclipse.jdt.core.tests.util.Util;
import org.eclipse.jdt.internal.compiler.ClassFile;
import org.eclipse.jdt.internal.compiler.IProblemFactory;
import org.eclipse.jdt.internal.compiler.batch.FileSystem;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
import org.eclipse.jdt.internal.compiler.env.IBinaryField;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblem;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.eval.EvaluationContext;
import org.eclipse.jdt.internal.eval.EvaluationResult;
import org.eclipse.jdt.internal.eval.GlobalVariable;
import org.eclipse.jdt.internal.eval.IRequestor;

public class SimpleTest {
	static final String JRE_PATH = Util.getJREDirectory();
	static final String[] COMPILATION_CLASSPATH = Util.concatWithClassLibs(Util.getOutputDirectory(), false);
	static final String[] RUNTIME_CLASSPATH =  new String[] {Util.getOutputDirectory()};
	static final String TARGET_PATH = Util.getOutputDirectory() + File.separator + "evaluation";
	protected EvaluationContext context;
	protected LocalVirtualMachine launchedVM;
	protected TargetInterface target;
	protected Requestor requestor;

	class Requestor implements IRequestor {
		int globalProblemCount = 0;
		public boolean acceptClassFiles(ClassFile[] classFiles, char[] codeSnippetClassName) {
			try {
				SimpleTest.this.target.sendClasses(codeSnippetClassName != null, classFiles);
			} catch (TargetException e) {
				return false;
			}
			if (codeSnippetClassName != null) {
				TargetInterface.Result result = SimpleTest.this.target.getResult();
				if (result.displayString == null) {
					System.out.println("(No explicit return value)");
				} else {
					System.out.print("(");
					System.out.print(result.typeName);
					System.out.print(") ");
					System.out.println(result.displayString);
				}
			} else {
				for (int i = 0, length = classFiles.length; i < length; i++) {
					char[][] compoundName = classFiles[i].getCompoundName();
					if (new String(compoundName[compoundName.length-1]).startsWith("GlobalVariable")) {
						try {
							IBinaryField[] fields = new ClassFileReader(classFiles[i].getBytes(), null).getFields();
							if (fields != null) {
								for (int j = 0; j < fields.length; j++) {
									TargetInterface.Result result = SimpleTest.this.target.getResult();
									if (result.displayString == null) {
										System.out.println("(No explicit return value)");
									} else {
										System.out.print("(");
										System.out.print(result.typeName);
										System.out.print(") ");
										System.out.println(result.displayString);
									}
								}
							}
						} catch (ClassFormatException e) {
							e.printStackTrace();
						}
					}
				}
			}
			return true;
		}
		public void acceptProblem(CategorizedProblem problem, char[] fragmentSource, int fragmentKind) {
			int localErrorCount = 0;
			this.globalProblemCount++;
			char[] source = fragmentSource;
			if (localErrorCount == 0)
				System.out.println("----------");
			if (fragmentKind == EvaluationResult.T_INTERNAL) {
				System.out.print(this.globalProblemCount + (problem.isError() ? ". INTERNAL ERROR" : ". INTERNAL WARNING"));
				System.out.print(" in generated compilation unit");
			} else {
				System.out.print(this.globalProblemCount + (problem.isError() ? ". ERROR" : ". WARNING"));
				System.out.print(" in ");
				switch (fragmentKind) {
					case EvaluationResult.T_PACKAGE:
						System.out.print("package");
						break;
					case EvaluationResult.T_IMPORT:
						System.out.print("import");
						break;
					case EvaluationResult.T_CODE_SNIPPET:
						System.out.print("code snippet");
						break;
					case EvaluationResult.T_VARIABLE:
						int line = problem.getSourceLineNumber();
						if (line == -1) {
							System.out.print("variable type");
							source = findVar(fragmentSource).getTypeName();
						} else if (line == 0) {
							System.out.print("variable name");
							source = findVar(fragmentSource).getName();
						} else {
							System.out.print("variable initializer");
							source = findVar(fragmentSource).getInitializer();
						}
						break;
				}
			}
			System.out.println(errorReportSource((DefaultProblem)problem, source));
			System.out.println(problem.getMessage());
			System.out.println("----------");
			if (problem.isError())
				localErrorCount++;
		}
	}
/**
 * Build a char array from the given lines
 */
protected char[] buildCharArray(String[] lines) {
	StringBuffer buffer = new StringBuffer();
	for (int i = 0; i < lines.length; i++) {
		buffer.append(lines[i]);
		if (i < lines.length -1) {
			buffer.append("\n");
		}
	}
	int length = buffer.length();
	char[] result = new char[length];
	buffer.getChars(0, length, result, 0);
	return result;
}
protected String errorReportSource(DefaultProblem problem, char[] source) {
	//extra from the source the innacurate     token
	//and "highlight" it using some underneath ^^^^^
	//put some context around too.

	//this code assumes that the font used in the console is fixed size

	//sanity .....
	if ((problem.getSourceStart() > problem.getSourceEnd()) || ((problem.getSourceStart() < 0) && (problem.getSourceEnd() < 0)))
		return "\n!! no source information available !!";

	//regular behavior....(slow code)

	final char SPACE = '\u0020';
	final char MARK = '^';
	final char TAB = '\t';
	//the next code tries to underline the token.....
	//it assumes (for a good display) that token source does not
	//contain any \r \n. This is false on statements !
	//(the code still works but the display is not optimal !)

	//compute the how-much-char we are displaying around the inaccurate token
	int begin = problem.getSourceStart() >= source.length ? source.length - 1 : problem.getSourceStart();
	int relativeStart = 0;
	int end = problem.getSourceEnd() >= source.length ? source.length - 1 : problem.getSourceEnd();
	int relativeEnd = 0;
	label : for (relativeStart = 0;; relativeStart++) {
		if (begin == 0)
			break label;
		if ((source[begin - 1] == '\n') || (source[begin - 1] == '\r'))
			break label;
		begin--;
	}
	label : for (relativeEnd = 0;; relativeEnd++) {
		if ((end + 1) >= source.length)
			break label;
		if ((source[end + 1] == '\r') || (source[end + 1] == '\n')) {
			break label;
		}
		end++;
	}
	//extract the message form the source
	char[] extract = new char[end - begin + 1];
	System.arraycopy(source, begin, extract, 0, extract.length);
	char c;
	//remove all SPACE and TAB that begin the error message...
	int trimLeftIndex = 0;
	while (((c = extract[trimLeftIndex++]) == TAB) || (c == SPACE)) {
	}
	System.arraycopy(extract, trimLeftIndex - 1, extract = new char[extract.length - trimLeftIndex + 1], 0, extract.length);
	relativeStart -= trimLeftIndex;
	//buffer spaces and tabs in order to reach the error position
	int pos = 0;
	char[] underneath = new char[extract.length]; // can't be bigger
	for (int i = 0; i <= relativeStart; i++) {
		if (extract[i] == TAB) {
			underneath[pos++] = TAB;
		} else {
			underneath[pos++] = SPACE;
		}
	}
	//mark the error position
	for (int i = problem.getSourceStart(); i <= (problem.getSourceEnd() >= source.length ? source.length - 1 : problem.getSourceEnd()); i++)
		underneath[pos++] = MARK;
	//resize underneathto remove 'null' chars
	System.arraycopy(underneath, 0, underneath = new char[pos], 0, pos);
	return
		((problem.getSourceLineNumber() > 0) ?
			(" (at line " + String.valueOf(problem.getSourceLineNumber()) + ")") :
			""
		) +
		"\n\t" + new String(extract) + "\n\t" + new String(underneath);
}
protected GlobalVariable findVar(char[] varName) {
	GlobalVariable[] vars = this.context.allVariables();
	for (int i = 0; i < vars.length; i++) {
		GlobalVariable var = vars[i];
		if (CharOperation.equals(var.getName(), varName)) {
			return var;
		}
	}
	return null;
}
protected INameEnvironment getEnv() {

	return new FileSystem(COMPILATION_CLASSPATH, new String[0], null);
}
protected IProblemFactory getProblemFactory() {
	return new DefaultProblemFactory(java.util.Locale.getDefault());
}
protected void startEvaluationContext() throws TargetException {
	LocalVMLauncher launcher = LocalVMLauncher.getLauncher();
	launcher.setVMPath(JRE_PATH);
	launcher.setClassPath(RUNTIME_CLASSPATH);
	int evalPort = Util.getFreePort();
	launcher.setEvalPort(evalPort);
	launcher.setEvalTargetPath(TARGET_PATH);
	this.launchedVM = launcher.launch();

	(new Thread() {
		public void run() {
			try {
				java.io.InputStream in = SimpleTest.this.launchedVM.getInputStream();
				int read = 0;
				while (read != -1) {
					try {
						read = in.read();
					} catch (java.io.IOException e) {
						read = -1;
					}
					if (read != -1) {
						System.out.print((char)read);
					}
				}
			} catch (TargetException e) {
			}
		}
	}).start();

	(new Thread() {
		public void run() {
			try {
				java.io.InputStream in = SimpleTest.this.launchedVM.getErrorStream();
				int read = 0;
				while (read != -1) {
					try {
						read = in.read();
					} catch (java.io.IOException e) {
						read = -1;
					}
					if (read != -1) {
						System.out.print((char)read);
					}
				}
			} catch (TargetException e) {
			}
		}
	}).start();

	this.requestor = new Requestor();
	this.target = new TargetInterface();
	this.target.connect("localhost", evalPort, 30000); // allow 30s max to connect (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=188127)
	this.context = new EvaluationContext();
}
protected void stopEvaluationContext() {
	try {
		this.target.disconnect(); // Close the socket first so that the OS resource has a chance to be freed.
		int retry = 0;
		while (this.launchedVM.isRunning() && (++retry < 20)) {
			try {
				Thread.sleep(retry * 100);
			} catch (InterruptedException e) {
			}
		}
		if (this.launchedVM.isRunning()) {
			this.launchedVM.shutDown();
		}
		this.context = null;
	} catch (TargetException e) {
		throw new Error(e.getMessage());
	}
}
}
