/*******************************************************************************
 * Copyright (c) 2005 BEA Systems 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:
 *     BEA Systems - initial implementation
 *     
 *******************************************************************************/
package org.eclipse.jst.jsp.core.internal.java.jspel;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.jface.text.Position;
import org.eclipse.jst.jsp.core.internal.contentmodel.TaglibController;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.CMDocumentImpl;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.TLDCMDocumentManager;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.TaglibTracker;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDFunction;
import org.eclipse.jst.jsp.core.internal.java.JSPTranslator;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection;

public class ELGeneratorVisitor implements JSPELParserVisitor {
	
	private static final String ENDL = "\n"; //$NON-NLS-1$
	
	private static final String fExpressionHeader1 = "public String _elExpression"; //$NON-NLS-1$
	private static final String fExpressionHeader2 = "()" + ENDL + //$NON-NLS-1$
	"\t\tthrows java.io.IOException, javax.servlet.ServletException {" + ENDL + //$NON-NLS-1$
	"javax.servlet.jsp.PageContext pageContext = null;" + ENDL + //$NON-NLS-1$
	"java.util.Map param = null;" + ENDL + //$NON-NLS-1$
	"java.util.Map paramValues = null;" + ENDL + //$NON-NLS-1$
	"java.util.Map header = null;" + ENDL + //$NON-NLS-1$ 
	"java.util.Map headerValues = null;" + ENDL + //$NON-NLS-1$
	"java.util.Map cookie = null;" + ENDL + //$NON-NLS-1$ 
	"java.util.Map initParam = null;" + ENDL + //$NON-NLS-1$
	"java.util.Map pageScope = null;" + ENDL + //$NON-NLS-1$
	"java.util.Map requestScope = null;" + ENDL + //$NON-NLS-1$
	"java.util.Map sessionScope = null;" + ENDL + //$NON-NLS-1$
	"java.util.Map applicationScope = null;" + ENDL + //$NON-NLS-1$
	"return \"\"+"; //$NON-NLS-1$
	
	private static final String fJspImplicitObjects[] = { "pageContext" }; //$NON-NLS-1$
	
	private static final String fJspImplicitMaps[] = { 	"param", "paramValues", "header", "headerValues", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
														"cookie", "initParam", "pageScope", "requestScope", "sessionScope",  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
														"applicationScope" }; //$NON-NLS-1$
	
	private static final HashMap fJSPImplicitObjectMap = new HashMap(fJspImplicitObjects.length);
	static {
		for(int i = 0; i < fJspImplicitObjects.length; i++) {
			fJSPImplicitObjectMap.put(fJspImplicitObjects[i], new Boolean(true));
		}
		
		for(int i = 0; i < fJspImplicitMaps.length; i++) {
			fJSPImplicitObjectMap.put(fJspImplicitMaps[i], new Boolean(false));
		}
	}
	
	private static final String fFooter = " ;" + ENDL + "}" + ENDL; //$NON-NLS-1$ //$NON-NLS-2$

	private StringBuffer fResult;
	private Map fCodeMap;
	private int fOffsetInUserCode;
	private int methodCounter = 0;
	private JSPTranslator fTranslator = null;
	private int fContentStart;
	private static Map fOperatorMap;
	
	// this flag lets us know if we were unable to generate for some reason.  One possible reason is that the expression 
	// contains a reference to a variable for which information is only available at runtime.
	private boolean fCanGenerate = true;

	/**
	 * Tranlsation of XML-style operators to java
	 */
	static {
		fOperatorMap = new HashMap();
		fOperatorMap.put("gt", ">"); //$NON-NLS-1$ //$NON-NLS-2$
		fOperatorMap.put("lt", "<"); //$NON-NLS-1$ //$NON-NLS-2$
		fOperatorMap.put("ge", ">="); //$NON-NLS-1$ //$NON-NLS-2$
		fOperatorMap.put("le", "<="); //$NON-NLS-1$ //$NON-NLS-2$
		fOperatorMap.put("mod", "%"); //$NON-NLS-1$ //$NON-NLS-2$
		fOperatorMap.put("eq", "=="); //$NON-NLS-1$ //$NON-NLS-2$
	}
	
	/**
	 * The constructor squirrels away a few things we'll need later
	 * 
	 * @param result
	 * @param codeMap
	 * @param translator
	 * @param jspReferenceRegion
	 * @param contentStart
	 */
	public ELGeneratorVisitor(StringBuffer result, Map codeMap, JSPTranslator translator, ITextRegionCollection jspReferenceRegion, int contentStart)
	{
		fResult = result;
		fCodeMap = codeMap;
		fOffsetInUserCode = result.length();
		fContentStart = contentStart;
		fTranslator = translator;
	}

	/**
	 * Append a token to the output stream.  Automatically calculating mapping.
	 * 
	 * @param token
	 */
	private void append(Token token)
	{
		append(token.image, token.beginColumn - 1, token.endColumn);
	}
	
	/**
	 * Append a translation for the corresponding input token.
	 * 
	 * @param translated
	 * @param token
	 */
	private void append(String translated, Token token)
	{
		append(translated, token.beginColumn - 1, token.endColumn);
	}

	/**
	 * Append a string explicitly giving the input mapping.
	 * 
	 * @param newText
	 * @param jspPositionStart
	 * @param jspPositionEnd
	 */
	private void append(String newText, int jspPositionStart, int jspPositionEnd)
	{
		fResult.append(newText);
		Position javaRange = new Position(fOffsetInUserCode, newText.length());
		Position jspRange = new Position(fContentStart + jspPositionStart, jspPositionEnd - jspPositionStart);

		fCodeMap.put(javaRange, jspRange);
		fOffsetInUserCode += newText.length();
	}
	
	/**
	 * Append text that will be unmapped and therefore will not be available for completion.
	 * 
	 * @param newText
	 */
	private void append(String newText)
	{
		fResult.append(newText);
		fOffsetInUserCode += newText.length();
	}
	
	/**
	 * Generate a function invocation.
	 * 
	 * @param fullFunctionName
	 * @return
	 */
	protected String genFunction(String fullFunctionName) {
		TLDCMDocumentManager docMgr = TaglibController.getTLDCMDocumentManager(fTranslator.getStructuredDocument());
		int colonIndex = fullFunctionName.indexOf(':');
		String prefix = fullFunctionName.substring(0, colonIndex);
		String functionName = fullFunctionName.substring(colonIndex + 1);
		if (docMgr == null)
			return null;
		
		Iterator taglibs = docMgr.getCMDocumentTrackers(fTranslator.getCurrentNode().getStartOffset()).iterator();
		while (taglibs.hasNext()) {
			TaglibTracker tracker = (TaglibTracker)taglibs.next();
			if(tracker.getPrefix().equals(prefix)) {
				CMDocumentImpl doc = (CMDocumentImpl)tracker.getDocument();
				
				List functions = doc.getFunctions();
				for(Iterator it = functions.iterator(); it.hasNext(); ) {
					TLDFunction function = (TLDFunction)it.next();
					if(function.getName().equals(functionName)) {
						return function.getClassName() + "." + function.getName(); //$NON-NLS-1$
					}
				}
			}
		}
		return null;
	}

	/**
	 * Handle a simple node -- fallback
	 */
	public Object visit(SimpleNode node, Object data) {
		return(node.childrenAccept(this, data));
	}

	/**
	 * Handle top-level expression
	 */
	public Object visit(ASTExpression node, Object data) {
		int start = node.getFirstToken().beginColumn - 1;
		int end = node.lastToken.endColumn - 1;
		append(fExpressionHeader1, start, start);
		append(Integer.toString(methodCounter++), start, start);
		append(fExpressionHeader2, start, start);
		
		Object retval = node.childrenAccept(this, data);

		append(fFooter, end, end);
		
		// something is preventing good code generation so empty out the result and the map.
		if(!fCanGenerate) {
			fResult.delete(0, fResult.length());
			fCodeMap.clear();			
		}
		return retval;
	}

	/**
	 * Generically generate an operator node.
	 * 
	 * @param node
	 * @param data
	 */
	private void generateOperatorNode(ASTOperatorExpression node, Object data) {
		for(int i = 0; i < node.children.length; i++) {
			node.children[i].jjtAccept(this, data);
			if( node.children.length - i > 1) {
				appendOperator((Token)node.getOperatorTokens().get(i));
			}
		}
	}
	
	/**
	 * Append an operator to the output stream after translation (if any)
	 * 
	 * @param token
	 * @return
	 */
	private String appendOperator(Token token) {
		String tokenImage = token.image.trim();
		String translated = (String)fOperatorMap.get(tokenImage);
		if(null != translated) {
			append(translated, token);
		} else {
			append(token);
		}
		return(translated);
	}

	/**
	 * Handle or Expression
	 */
	public Object visit(ASTOrExpression node, Object data) {
		generateOperatorNode(node, data);
		return(null);
	}


	/**
	 * Handle and expression 
	 */
	public Object visit(ASTAndExpression node, Object data) {
		generateOperatorNode(node, data);
		return(null);
	}


	/**
	 * Handle equality
	 */
	public Object visit(ASTEqualityExpression node, Object data) {
		generateOperatorNode(node, data);
		return(null);
	}


	/**
	 * Handle Relational
	 */
	public Object visit(ASTRelationalExpression node, Object data) {
		generateOperatorNode(node, data);
		return(null);
	}


	/**
	 * Handle addition
	 */
	public Object visit(ASTAddExpression node, Object data) {
		generateOperatorNode(node, data);
		return(null);
	}


	/**
	 * Handle multiply
	 */
	public Object visit(ASTMultiplyExpression node, Object data) {
		generateOperatorNode(node, data);
		return(null);
	}


	/** 
	 * Choice Expression (ternary operator)
	 */
	public Object visit(ASTChoiceExpression node, Object data) {
		node.children[0].jjtAccept(this, data);
		append("?"); //$NON-NLS-1$
		node.children[1].jjtAccept(this, data);
		append(":"); //$NON-NLS-1$
		node.children[2].jjtAccept(this,data);
		return null;
	}


	/**
	 * Handle unary
	 */
	public Object visit(ASTUnaryExpression node, Object data) {
		if(JSPELParserConstants.EMPTY == node.firstToken.kind) {
			append("((null == "); //$NON-NLS-1$
			node.childrenAccept(this, data);
			append(") || ("); //$NON-NLS-1$
			node.childrenAccept(this, data);
			append(").isEmpty())"); //$NON-NLS-1$
		} else if(JSPELParserConstants.NOT1 == node.firstToken.kind || JSPELParserConstants.NOT2 == node.firstToken.kind) {
			append("(!"); //$NON-NLS-1$
			node.childrenAccept(this, data);
			append(")"); //$NON-NLS-1$
		} else if(JSPELParserConstants.MINUS == node.firstToken.kind) {
			append("(-"); //$NON-NLS-1$
			node.childrenAccept(this, data);
			append(")"); //$NON-NLS-1$
		} else {
			node.childrenAccept(this, data);
		}
		return null;
	}


	/**
	 * Value node
	 */
	public Object visit(ASTValue node, Object data) {
		return node.childrenAccept(this, data);	
	}


	/**
	 * Value Prefix
	 */
	public Object visit(ASTValuePrefix node, Object data) {
		// this is a raw identifier.  May sure it's an implicit object.
		// This is the primary plae where modification is needed to 
		// support JSF backing beans.
		if(null == node.children) {
			if(isCompletingObject(node.firstToken.image)) {
				append(node.firstToken);
			} else {
				fCanGenerate = false;
			}
			return(null);
		}
		return node.childrenAccept(this, data);
	}


	/**
	 * Function for testing implicit objects.
	 * 
	 * @param image
	 * @return
	 */
	private boolean isCompletingObject(String image) {
		Boolean value = (Boolean)fJSPImplicitObjectMap.get(image);
		return null == value ? false : value.booleanValue();
	}

	/**
	 * Value suffix
	 */
	public Object visit(ASTValueSuffix node, Object data) {
		if(JSPELParserConstants.LBRACKET == node.firstToken.kind) {
			fCanGenerate = false;
		} else if(null != node.getPropertyNameToken()) {
			Token suffix = node.getPropertyNameToken();
			String ucaseName = suffix.image.substring(0, 1).toUpperCase() + suffix.image.substring(1, suffix.image.length()); 
			append(node.firstToken);
			append("get" + ucaseName + "()", suffix); //$NON-NLS-1$ //$NON-NLS-2$
		} else {
			append(node.firstToken);
		}
		return null;
	}


	/**
	 * Function invocation
	 */
	public Object visit(ASTFunctionInvocation node, Object data) {
		String functionTranslation = genFunction(node.getFullFunctionName());
		if(null != functionTranslation)
		{
			append(functionTranslation + "(", node.getFirstToken()); //$NON-NLS-1$
			for(int i = 0; i < node.children.length; i++) {
				node.children[i].jjtAccept(this, data);
				if( node.children.length - i > 1){
					append(","); //$NON-NLS-1$
				}
			}
			append(")"); //$NON-NLS-1$
		}
		return null;
	}

	/**
	 * Literal
	 */
	public Object visit(ASTLiteral node, Object data) {
		// TODO any further translation needed?
		append(node.firstToken);
		return null;
	}
}
