/*******************************************************************************
 * Copyright (c) 2000, 2010 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 org.eclipse.jdt.core.CompletionContext;
import org.eclipse.jdt.core.CompletionProposal;
import org.eclipse.jdt.core.CompletionRequestor;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.compiler.*;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.internal.codeassist.ISelectionRequestor;

/**
 * Maps back and forth a code snippet to a compilation unit.
 * The structure of the compilation unit is as follows:
 * <pre>
 * [package <package name>;]
 * [import <import name>;]*
 * public class <code snippet class name> extends <global variable class name> {
 *   [<declaring type> val$this;]
 *   public void run() {
 *     <code snippet>
 *   }
 * }
 * </pre>
 */
class CodeSnippetToCuMapper implements EvaluationConstants {
	/**
	 * The generated compilation unit.
	 */
	public char[] cuSource;
	
	/**
	 * Where the code snippet starts in the generated compilation unit.
	 */
	public int lineNumberOffset = 0;
	public int startPosOffset = 0;

	// Internal fields
	char[] codeSnippet;
	char[] snippetPackageName;
	char[][] snippetImports;
	char[] snippetClassName; 
	char[] snippetVarClassName;
	char[] snippetDeclaringTypeName;

	// Mapping of external local variables
	char[][] localVarNames;
	char[][] localVarTypeNames;
	
/**
 * Rebuild source in presence of external local variables
 */
 public CodeSnippetToCuMapper(char[] codeSnippet, char[] packageName, char[][] imports, char[] className, char[] varClassName, char[][] localVarNames, char[][] localVarTypeNames, int[] localVarModifiers, char[] declaringTypeName, String lineSeparator) {
	this.codeSnippet = codeSnippet;
	this.snippetPackageName = packageName;
	this.snippetImports = imports;
	this.snippetClassName = className;
	this.snippetVarClassName = varClassName;
	this.localVarNames = localVarNames;
	this.localVarTypeNames = localVarTypeNames;
	this.snippetDeclaringTypeName = declaringTypeName;
	buildCUSource(lineSeparator);
}
private void buildCUSource(String lineSeparator) {
	StringBuffer buffer = new StringBuffer();

	// package declaration
	if (this.snippetPackageName != null && this.snippetPackageName.length != 0) {
		buffer.append("package "); //$NON-NLS-1$
		buffer.append(this.snippetPackageName);
		buffer.append(";").append(lineSeparator); //$NON-NLS-1$
		this.lineNumberOffset++;
	}

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

	// class declaration
	buffer.append("public class "); //$NON-NLS-1$
	buffer.append(this.snippetClassName);

	// super class is either a global variable class or the CodeSnippet class
	if (this.snippetVarClassName != null) {
		buffer.append(" extends "); //$NON-NLS-1$
		buffer.append(this.snippetVarClassName);
	} else {
		buffer.append(" extends "); //$NON-NLS-1$
		buffer.append(PACKAGE_NAME);
		buffer.append("."); //$NON-NLS-1$
		buffer.append(ROOT_CLASS_NAME);
	}
	buffer.append(" {").append(lineSeparator); //$NON-NLS-1$
	this.lineNumberOffset++;

	if (this.snippetDeclaringTypeName != null){
		buffer.append("  "); //$NON-NLS-1$
		buffer.append(this.snippetDeclaringTypeName);
		buffer.append(" "); //$NON-NLS-1$
		buffer.append(DELEGATE_THIS); // val$this
		buffer.append(';').append(lineSeparator);
		this.lineNumberOffset++;
	}
	// add some storage location for local variable persisted state
	if (this.localVarNames != null) {
		for (int i = 0, max = this.localVarNames.length; i < max; i++) {
			buffer.append("    "); //$NON-NLS-1$
			buffer.append(this.localVarTypeNames[i]);
			buffer.append(" "); //$NON-NLS-1$
			buffer.append(LOCAL_VAR_PREFIX); // val$...
			buffer.append(this.localVarNames[i]);
			buffer.append(';').append(lineSeparator);
			this.lineNumberOffset++;
		}
	}
	// run() method declaration
	buffer.append("public void run() throws Throwable {").append(lineSeparator); //$NON-NLS-1$
	this.lineNumberOffset++;
	this.startPosOffset = buffer.length();
	buffer.append(this.codeSnippet);
	// a line separator is required after the code snippet source code
	// in case the code snippet source code ends with a line comment
	// http://dev.eclipse.org/bugs/show_bug.cgi?id=14838
	buffer.append(lineSeparator).append('}').append(lineSeparator);

	// end of class declaration
	buffer.append('}').append(lineSeparator);

	// store result
	int length = buffer.length();
	this.cuSource = new char[length];
	buffer.getChars(0, length, this.cuSource, 0);
}
/**
 * Returns a completion requestor that wraps the given requestor and shift the results
 * according to the start offset and line number offset of the code snippet in the generated compilation unit. 
 */
public CompletionRequestor getCompletionRequestor(final CompletionRequestor originalRequestor) {
	return new CompletionRequestor() {
		public void accept(CompletionProposal proposal) {
			switch(proposal.getKind()) {
				case CompletionProposal.TYPE_REF:
					int flags = proposal.getFlags();
					if((flags & Flags.AccEnum) == 0 &&
							(flags & Flags.AccInterface) == 0) {
						// Remove completion on generated class name or generated global variable class name
						char[] packageName = proposal.getDeclarationSignature();
						char[] className = Signature.getSignatureSimpleName(proposal.getSignature());
						if (CharOperation.equals(packageName, CodeSnippetToCuMapper.this.snippetPackageName) 
								&& (CharOperation.equals(className, CodeSnippetToCuMapper.this.snippetClassName)
									|| CharOperation.equals(className, CodeSnippetToCuMapper.this.snippetVarClassName))) return;
						
						if (CharOperation.equals(packageName, PACKAGE_NAME) 
								&& CharOperation.equals(className, ROOT_CLASS_NAME)) return;
					}
					break;
				case CompletionProposal.METHOD_REF:
				case CompletionProposal.METHOD_DECLARATION:
				case CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER:
					// Remove completion on generated method
					char[] declaringTypePackageName = Signature.getSignatureQualifier(proposal.getDeclarationSignature());
					char[] declaringTypeName = Signature.getSignatureSimpleName(proposal.getDeclarationSignature());
					
					if (CharOperation.equals(declaringTypePackageName, CodeSnippetToCuMapper.this.snippetPackageName) 
							&& CharOperation.equals(declaringTypeName, CodeSnippetToCuMapper.this.snippetClassName)) return;
					
					if (CharOperation.equals(declaringTypePackageName, PACKAGE_NAME) 
							&& CharOperation.equals(declaringTypeName, ROOT_CLASS_NAME)) return;
					break;
			}
			originalRequestor.accept(proposal);
		}
		
		public void completionFailure(IProblem problem) {
			problem.setSourceStart(problem.getSourceStart() - CodeSnippetToCuMapper.this.startPosOffset);
			problem.setSourceEnd(problem.getSourceEnd() - CodeSnippetToCuMapper.this.startPosOffset);
			problem.setSourceLineNumber(problem.getSourceLineNumber() -  CodeSnippetToCuMapper.this.lineNumberOffset);
			originalRequestor.completionFailure(problem);
		}
		
		public void acceptContext(CompletionContext context) {
			originalRequestor.acceptContext(context);
		}
		
		public void beginReporting() {
			originalRequestor.beginReporting();
		}
		
		public void endReporting() {
			originalRequestor.endReporting();
		}
		
		public boolean isIgnored(int completionProposalKind) {
			return originalRequestor.isIgnored(completionProposalKind);
		}
		
		public void setIgnored(int completionProposalKind, boolean ignore) {
			originalRequestor.setIgnored(completionProposalKind, ignore);
		}
		
		public boolean isAllowingRequiredProposals(int mainKind, int requiredKind) {
			return originalRequestor.isAllowingRequiredProposals(mainKind, requiredKind);
		}

		public void setAllowsRequiredProposals(int mainKind, int requiredKind, boolean allow) {
			originalRequestor.setAllowsRequiredProposals(mainKind, requiredKind, allow);
		}
	};
}
public char[] getCUSource(String lineSeparator) {
	if (this.cuSource == null) {
		buildCUSource(lineSeparator);
	}
	return this.cuSource;
}
/**
 * Returns the type of evaluation that corresponds to the given line number in the generated compilation unit.
 */
public int getEvaluationType(int lineNumber) {
	int currentLine = 1;

	// check package declaration	
	if (this.snippetPackageName != null && this.snippetPackageName.length != 0) {
		if (lineNumber == 1) {
			return EvaluationResult.T_PACKAGE;
		}
		currentLine++;
	}

	// check imports
	char[][] imports = this.snippetImports;
	if ((currentLine <= lineNumber) && (lineNumber < (currentLine + imports.length))) {
		return EvaluationResult.T_IMPORT;
	}
	currentLine += imports.length + 1; // + 1 to skip the class declaration line

	// check generated fields
	currentLine +=
		(this.snippetDeclaringTypeName == null ? 0 : 1) 
		+ (this.localVarNames == null ? 0 : this.localVarNames.length);
	if (currentLine > lineNumber) {
		return EvaluationResult.T_INTERNAL;
	}
	currentLine ++; // + 1 to skip the method declaration line

	// check code snippet
	if (currentLine >= this.lineNumberOffset) {
		return EvaluationResult.T_CODE_SNIPPET;
	}

	// default
	return EvaluationResult.T_INTERNAL;
}
/**
 * Returns the import defined at the given line number. 
 */
public char[] getImport(int lineNumber) {
	int importStartLine = this.lineNumberOffset - 1 - this.snippetImports.length;
	return this.snippetImports[lineNumber - importStartLine];
}
/**
 * Returns a selection requestor that wraps the given requestor and shift the problems
 * according to the start offset and line number offset of the code snippet in the generated compilation unit. 
 */
public ISelectionRequestor getSelectionRequestor(final ISelectionRequestor originalRequestor) {
	return new ISelectionRequestor() {
		public void acceptType(char[] packageName, char[] typeName, int modifiers, boolean isDeclaration, char[] uniqueKey, int start, int end) {
			originalRequestor.acceptType(packageName, typeName, modifiers, isDeclaration, uniqueKey, start, end);
		}
		public void acceptError(CategorizedProblem error) {
			error.setSourceLineNumber(error.getSourceLineNumber() -  CodeSnippetToCuMapper.this.lineNumberOffset);
			error.setSourceStart(error.getSourceStart() - CodeSnippetToCuMapper.this.startPosOffset);
			error.setSourceEnd(error.getSourceEnd() - CodeSnippetToCuMapper.this.startPosOffset);
			originalRequestor.acceptError(error);
		}
		public void acceptField(char[] declaringTypePackageName, char[] declaringTypeName, char[] name, boolean isDeclaration, char[] uniqueKey, int start, int end) {
			originalRequestor.acceptField(declaringTypePackageName, declaringTypeName, name, isDeclaration, uniqueKey, start, end);
		}
		public void acceptMethod(char[] declaringTypePackageName, char[] declaringTypeName, String enclosingDeclaringTypeSignature, char[] selector, char[][] parameterPackageNames, char[][] parameterTypeNames, String[] parameterSignatures, char[][] typeParameterNames, char[][][] typeParameterBoundNames, boolean isConstructor, boolean isDeclaration, char[] uniqueKey, int start, int end) {
			originalRequestor.acceptMethod(declaringTypePackageName, declaringTypeName, enclosingDeclaringTypeSignature, selector, parameterPackageNames, parameterTypeNames, parameterSignatures, typeParameterNames, typeParameterBoundNames, isConstructor, isDeclaration, uniqueKey, start, end);
		}
		public void acceptPackage(char[] packageName) {
			originalRequestor.acceptPackage(packageName);
		}
		
		public void acceptTypeParameter(char[] declaringTypePackageName, char[] declaringTypeName, char[] typeParameterName, boolean isDeclaration, int start, int end) {
			originalRequestor.acceptTypeParameter(declaringTypePackageName, declaringTypeName, typeParameterName, isDeclaration, start, end);
		}
		public void acceptMethodTypeParameter(char[] declaringTypePackageName, char[] declaringTypeName, char[] selector, int selectorStart, int selectorEnd, char[] typeParameterName,boolean isDeclaration, int start, int end) {
			originalRequestor.acceptMethodTypeParameter(declaringTypePackageName, declaringTypeName, selector, selectorStart, selectorEnd, typeParameterName, isDeclaration, start, end);
		}
	};
}
}
