/*******************************************************************************
 * Copyright (c) 2000, 2004 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.internal.eval;

import java.util.Map;

import org.eclipse.jdt.core.compiler.*;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.internal.compiler.ClassFile;
import org.eclipse.jdt.internal.compiler.Compiler;
import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
import org.eclipse.jdt.internal.compiler.IProblemFactory;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
import org.eclipse.jdt.internal.compiler.env.IBinaryType;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;

/**
 * A variables evaluator compiles the global variables of an evaluation context and returns
 * the corresponding class files. Or it reports problems against these variables.
 */
public class VariablesEvaluator extends Evaluator implements EvaluationConstants {
	int startPosOffset = 0;
/**
 * Creates a new global variables evaluator.
 */
VariablesEvaluator(EvaluationContext context, INameEnvironment environment, Map options, IRequestor requestor, IProblemFactory problemFactory) {
	super(context, environment, options, requestor, problemFactory);
}
/**
 * @see org.eclipse.jdt.internal.eval.Evaluator
 */
protected void addEvaluationResultForCompilationProblem(Map resultsByIDs, IProblem problem, char[] cuSource) {
	// set evaluation id and type to an internal problem by default
	char[] evaluationID = cuSource;
	int evaluationType = EvaluationResult.T_INTERNAL;

	int pbLine = problem.getSourceLineNumber();
	int currentLine = 1;

	// check package declaration	
	char[] packageName = getPackageName();
	if (packageName.length > 0) {
		if (pbLine == 1) {
			// set evaluation id and type
			evaluationID = packageName;
			evaluationType = EvaluationResult.T_PACKAGE;

			// shift line number, source start and source end
			problem.setSourceLineNumber(1);
			problem.setSourceStart(0);
			problem.setSourceEnd(evaluationID.length - 1);
		}
		currentLine++;
	}

	// check imports
	char[][] imports = this.context.imports;
	if ((currentLine <= pbLine) && (pbLine < (currentLine + imports.length))) {
		// set evaluation id and type
		evaluationID = imports[pbLine - currentLine];
		evaluationType = EvaluationResult.T_IMPORT;

		// shift line number, source start and source end
		problem.setSourceLineNumber(1);
		problem.setSourceStart(0);
		problem.setSourceEnd(evaluationID.length - 1);
	}
	currentLine += imports.length + 1; // + 1 to skip the class declaration line

	// check variable declarations
	int varCount = this.context.variableCount;
	if ((currentLine <= pbLine) && (pbLine < currentLine + varCount)) {
		GlobalVariable var = this.context.variables[pbLine - currentLine];
		
		// set evaluation id and type
		evaluationID = var.getName();
		evaluationType = EvaluationResult.T_VARIABLE;

		// shift line number, source start and source end
		int pbStart = problem.getSourceStart() - var.declarationStart;
		int pbEnd = problem.getSourceEnd() - var.declarationStart;
		int typeLength = var.getTypeName().length;
		if ((0 <= pbStart) && (pbEnd < typeLength)) {
			// problem on the type of the variable
			problem.setSourceLineNumber(-1);
		} else {
			// problem on the name of the variable
			pbStart -= typeLength + 1; // type length + space
			pbEnd -= typeLength + 1; // type length + space
			problem.setSourceLineNumber(0);
		}
		problem.setSourceStart(pbStart);
		problem.setSourceEnd(pbEnd);
	}
	currentLine = -1; // not needed any longer

	// check variable initializers
	for (int i = 0; i < varCount; i++) {
		GlobalVariable var = this.context.variables[i];
		char[] initializer = var.getInitializer();
		int initializerLength = initializer == null ? 0 : initializer.length;
		if ((var.initializerStart <= problem.getSourceStart()) && (problem.getSourceEnd() < var.initializerStart + var.name.length)) {
			/* Problem with the variable name.
			   Ignore because it must have already been reported
			   when checking the declaration.
			 */
			return;
		} else if ((var.initExpressionStart <= problem.getSourceStart()) && (problem.getSourceEnd() < var.initExpressionStart + initializerLength)) {
			// set evaluation id and type
			evaluationID = var.name;
			evaluationType = EvaluationResult.T_VARIABLE;

			// shift line number, source start and source end
			problem.setSourceLineNumber(pbLine - var.initializerLineStart + 1);
			problem.setSourceStart(problem.getSourceStart() - var.initExpressionStart);
			problem.setSourceEnd(problem.getSourceEnd() - var.initExpressionStart);

			break;
		}
	}

	EvaluationResult result = (EvaluationResult)resultsByIDs.get(evaluationID);
	if (result == null) {
		resultsByIDs.put(evaluationID, new EvaluationResult(evaluationID, evaluationType, new IProblem[] {problem}));
	} else {
		result.addProblem(problem);
	}
}
/**
 * @see org.eclipse.jdt.internal.eval.Evaluator
 */
protected char[] getClassName() {
	return CharOperation.concat(EvaluationConstants.GLOBAL_VARS_CLASS_NAME_PREFIX, Integer.toString(EvaluationContext.VAR_CLASS_COUNTER + 1).toCharArray());
}
/**
 * Creates and returns a compiler for this evaluator.
 */
Compiler getCompiler(ICompilerRequestor compilerRequestor) {
	Compiler compiler = super.getCompiler(compilerRequestor);
	
	// Initialize the compiler's lookup environment with the already compiled super class
	IBinaryType binaryType = this.context.getRootCodeSnippetBinary();
	if (binaryType != null) {
		compiler.lookupEnvironment.cacheBinaryType(binaryType, null /*no access restriction*/);
	}

	// and the installed global variable classes
	VariablesInfo installedVars = this.context.installedVars;
	if (installedVars != null) {
		ClassFile[] classFiles = installedVars.classFiles;
		for (int i = 0; i < classFiles.length; i++) {
			ClassFile classFile = classFiles[i];
			IBinaryType binary = null;
			try {
				binary = new ClassFileReader(classFile.getBytes(), null);
			} catch (ClassFormatException e) {
				e.printStackTrace(); // Should never happen since we compiled this type
			}
			compiler.lookupEnvironment.cacheBinaryType(binary, null /*no access restriction*/);
		}
	}
	
	return compiler;	
}
/**
 * Returns the name of package of the current compilation unit.
 */
protected char[] getPackageName() {
	return this.context.packageName;
}
/**
 * @see org.eclipse.jdt.internal.eval.Evaluator
 */
protected char[] getSource() {
	StringBuffer buffer = new StringBuffer();
	int lineNumberOffset = 1;
	
	// package declaration
	char[] packageName = getPackageName();
	if (packageName.length != 0) {
		buffer.append("package "); //$NON-NLS-1$
		buffer.append(packageName);
		buffer.append(';').append(this.context.lineSeparator);
		lineNumberOffset++;
	}

	// import declarations
	char[][] imports = this.context.imports;
	for (int i = 0; i < imports.length; i++) {
		buffer.append("import "); //$NON-NLS-1$
		buffer.append(imports[i]);
		buffer.append(';').append(this.context.lineSeparator);
		lineNumberOffset++;
	}

	// class declaration
	buffer.append("public class "); //$NON-NLS-1$
	buffer.append(getClassName());
	buffer.append(" extends "); //$NON-NLS-1$
	buffer.append(PACKAGE_NAME);
	buffer.append("."); //$NON-NLS-1$
	buffer.append(ROOT_CLASS_NAME);
	buffer.append(" {").append(this.context.lineSeparator); //$NON-NLS-1$
	lineNumberOffset++;
	this.startPosOffset = buffer.length();

	// field declarations
	GlobalVariable[] vars = this.context.variables;
	VariablesInfo installedVars = this.context.installedVars;
	for (int i = 0; i < this.context.variableCount; i++){
		GlobalVariable var = vars[i];
		buffer.append("\tpublic static "); //$NON-NLS-1$
		var.declarationStart = buffer.length();
		buffer.append(var.typeName);
		buffer.append(" "); //$NON-NLS-1$
		char[] varName = var.name;
		buffer.append(varName);
		buffer.append(';').append(this.context.lineSeparator);
		lineNumberOffset++;
	}

	// field initializations
	buffer.append("\tstatic {").append(this.context.lineSeparator); //$NON-NLS-1$
	lineNumberOffset++;
	for (int i = 0; i < this.context.variableCount; i++){
		GlobalVariable var = vars[i];
		char[] varName = var.name;
		GlobalVariable installedVar = installedVars == null ? null : installedVars.varNamed(varName);
		if (installedVar == null || !CharOperation.equals(installedVar.typeName, var.typeName)) {
			// Initialize with initializer if there was no previous value
			char[] initializer = var.initializer;
			if (initializer != null) {
				buffer.append("\t\ttry {").append(this.context.lineSeparator); //$NON-NLS-1$
				lineNumberOffset++;
				var.initializerLineStart = lineNumberOffset;
				buffer.append("\t\t\t"); //$NON-NLS-1$
				var.initializerStart = buffer.length();
				buffer.append(varName);
				buffer.append("= "); //$NON-NLS-1$
				var.initExpressionStart = buffer.length();
				buffer.append(initializer);
				lineNumberOffset += numberOfCRs(initializer);
				buffer.append(';').append(this.context.lineSeparator);
				buffer.append("\t\t} catch (Throwable e) {").append(this.context.lineSeparator); //$NON-NLS-1$
				buffer.append("\t\t\te.printStackTrace();").append(this.context.lineSeparator); //$NON-NLS-1$
				buffer.append("\t\t}").append(this.context.lineSeparator); //$NON-NLS-1$
				lineNumberOffset += 4; // 4 CRs
			}
		} else {
			// Initialize with previous value if name and type are the same
			buffer.append("\t\t"); //$NON-NLS-1$
			buffer.append(varName);
			buffer.append("= "); //$NON-NLS-1$
			char[] installedPackageName = installedVars.packageName;
			if (installedPackageName != null && installedPackageName.length != 0) {
				buffer.append(installedPackageName);
				buffer.append("."); //$NON-NLS-1$
			}
			buffer.append(installedVars.className);
			buffer.append("."); //$NON-NLS-1$
			buffer.append(varName);
			buffer.append(';').append(this.context.lineSeparator);
			lineNumberOffset++;
		}
	}
	buffer.append("\t}").append(this.context.lineSeparator); //$NON-NLS-1$
	
	// end of class declaration
	buffer.append('}').append(this.context.lineSeparator);

	// return result
	int length = buffer.length();
	char[] result = new char[length];
	buffer.getChars(0, length, result, 0);
	return result;
}
/**
 * Returns the number of cariage returns included in the given source.
 */
private int numberOfCRs(char[] source) {
	int numberOfCRs = 0;
	boolean lastWasCR = false;
	for (int i = 0; i < source.length; i++) {
		char currentChar = source[i];
		switch(currentChar){
			case '\r' :
				lastWasCR = true;
				numberOfCRs++;
				break;
			case '\n' :
				if (!lastWasCR) numberOfCRs++; // merge CR-LF
				lastWasCR = false;
				break;
			default :
				lastWasCR = false;
		}
	}
	return numberOfCRs;
}
}
