/*******************************************************************************
 * Copyright (c) 2006 Oracle Corporation.
 * 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:
 *    Cameron Bateman/Oracle - initial API and implementation
 *    
 ********************************************************************************/

package org.eclipse.jst.jsf.core.internal.contentassist.el;

import org.eclipse.jface.text.Region;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext;
import org.eclipse.jst.jsf.context.symbol.ISymbol;
import org.eclipse.jst.jsp.core.internal.java.jspel.ASTAddExpression;
import org.eclipse.jst.jsp.core.internal.java.jspel.ASTAndExpression;
import org.eclipse.jst.jsp.core.internal.java.jspel.ASTChoiceExpression;
import org.eclipse.jst.jsp.core.internal.java.jspel.ASTEqualityExpression;
import org.eclipse.jst.jsp.core.internal.java.jspel.ASTExpression;
import org.eclipse.jst.jsp.core.internal.java.jspel.ASTFunctionInvocation;
import org.eclipse.jst.jsp.core.internal.java.jspel.ASTLiteral;
import org.eclipse.jst.jsp.core.internal.java.jspel.ASTMultiplyExpression;
import org.eclipse.jst.jsp.core.internal.java.jspel.ASTOrExpression;
import org.eclipse.jst.jsp.core.internal.java.jspel.ASTRelationalExpression;
import org.eclipse.jst.jsp.core.internal.java.jspel.ASTUnaryExpression;
import org.eclipse.jst.jsp.core.internal.java.jspel.ASTValue;
import org.eclipse.jst.jsp.core.internal.java.jspel.ASTValuePrefix;
import org.eclipse.jst.jsp.core.internal.java.jspel.ASTValueSuffix;
import org.eclipse.jst.jsp.core.internal.java.jspel.JSPELParser;
import org.eclipse.jst.jsp.core.internal.java.jspel.JSPELParserConstants;
import org.eclipse.jst.jsp.core.internal.java.jspel.JSPELParserVisitor;
import org.eclipse.jst.jsp.core.internal.java.jspel.ParseException;
import org.eclipse.jst.jsp.core.internal.java.jspel.SimpleNode;
import org.eclipse.jst.jsp.core.internal.java.jspel.Token;

/**
 * Consumes an EL expression and converts into a completion prefix
 * 
 * @author cbateman
 *
 */
public final class ContentAssistParser 
{
    /**
     * @param relativePosition -- 1-based position in elText (first position is 1)
     * @param elText
     * @return a content assist strategy for the given position and el expression
     * or null if one cannot be determined
     */
    public static ContentAssistStrategy getPrefix(final int relativePosition, final String elText)
    {
        if (elText == null)
        {
            return null;
        }
        else if ("".equals(elText.trim())) //$NON-NLS-1$
        {
            return new IdCompletionStrategy("", "");  //$NON-NLS-1$//$NON-NLS-2$
        }
        
        PrefixVisitor visitor = getVisitorForPosition(relativePosition, elText);
        return visitor != null? visitor.getPrefix() : null;
    }
    
    /**
     * Get symbol and symbol region at given position in el string
     * @param context - IStructuredDocumentContext
     * @param relativePosition - position in el string
     * @param elText - el string
     * @return SymbolInfo. May be null.
     */
    public static SymbolInfo getSymbolInfo(IStructuredDocumentContext context, final int relativePosition, final String elText) {
        if (elText == null || "".equals(elText.trim())) //$NON-NLS-1$
        {
            return null;
        }
        PrefixVisitor visitor = getVisitorForPosition(relativePosition, elText);
        if (visitor != null) {
            SymbolInfo symbolInfo = visitor.getSymbolInfo(context);
            if (symbolInfo != null) {
                Region r = symbolInfo.getRelativeRegion();
                if (relativePosition > r.getOffset() && relativePosition <= r.getOffset() + r.getLength()) {
                    return symbolInfo;
                }
            }
        }
        return null;
    }

	private static PrefixVisitor getVisitorForPosition(final int relativePosition,
			final String elText) {
		final java.io.StringReader reader = new java.io.StringReader(elText);
        final JSPELParser  parser = new JSPELParser(reader);
        
        try
        {
            final ASTExpression expr = parser.Expression();
            final PrefixVisitor visitor = new PrefixVisitor(relativePosition, elText);
            expr.jjtAccept(visitor, null);
            return visitor;
        }
        catch (ParseException pe)
        {
            // TODO: handle parser by using current and expected tokens
        	return null;
        }
	}
    
    private static String substring(String s, Region r) {
        return s.substring(r.getOffset(), r.getOffset() + r.getLength());
    }
    
    private static class PrefixVisitor implements JSPELParserVisitor
    {
        private final int       _relativePos;
        private final String    _fullText;
        
        private String          _symbolPrefix; // = null; initialized as tree is visited
        private int             _prefixType;
        private boolean         _prefixResolved;  // = false; set to true when the prefix is resolved
        private int             _symbolStartPos = 1; // first char has position 1
        private int             _symbolEndPos = 0;
        
        PrefixVisitor(final int relativePos, final String fullText)
        {
            _relativePos = relativePos;
            _fullText = fullText;
        }
        
        /**
         * @return the prefix if resolved or null if not resolved
         */
        public ContentAssistStrategy getPrefix()
        {
            if (_prefixResolved)
            {
                switch(_prefixType)
                {
                    case ContentAssistStrategy.PREFIX_TYPE_DOT_COMPLETION:
                        return new FunctionCompletionStrategy(_symbolPrefix, getProposalStart());
                    
                    case ContentAssistStrategy.PREFIX_TYPE_ID_COMPLETION:
                        return new IdCompletionStrategy(_symbolPrefix, getProposalStart());
                    
                    case ContentAssistStrategy.PREFIX_TYPE_EMPTY_EXPRESSION:
                        return new IdCompletionStrategy("", getProposalStart()); //$NON-NLS-1$
                        
                    default:
                        // do nothing; fall-through to return null
                }
            }

            return null;
        }
        
        /**
         * @param context - IStructuredDocumentContext
         * @return symbol and symbol region if resolved, null otherwise
         */
        public SymbolInfo getSymbolInfo(IStructuredDocumentContext context) {
        	if (_prefixResolved && _symbolStartPos < _symbolEndPos) {
        		Region region = new Region(_symbolStartPos - 1, _symbolEndPos - _symbolStartPos + 1);
                ISymbol symbol = null;
                switch (_prefixType) {
                case ContentAssistStrategy.PREFIX_TYPE_ID_COMPLETION:
                    symbol = SymbolResolveUtil.getSymbolForVariable(context, substring(_fullText, region));
                    break;
                case ContentAssistStrategy.PREFIX_TYPE_DOT_COMPLETION:
                    symbol = SymbolResolveUtil.getSymbolForVariableSuffixExpr(context, _symbolPrefix + "." + substring(_fullText, region), _symbolEndPos == _fullText.length()); //$NON-NLS-1$
                    break;
                }
                if (symbol != null) {
                    return new SymbolInfo(symbol, region);
                }
        	}
        	return null;
        }

		private String getProposalStart() {
            if (_symbolStartPos <= _relativePos) {
                return _fullText.substring(_symbolStartPos - 1, _relativePos - 1);
            }
            return ""; //$NON-NLS-1$
		}
        
        public Object visit(ASTAddExpression node, Object data) 
        {
            return node.childrenAccept(this, data);
        }

		public Object visit(ASTAndExpression node, Object data) 
        {
            return node.childrenAccept(this, data);
        }

        public Object visit(ASTChoiceExpression node, Object data) 
        {
            return node.childrenAccept(this, data);
        }

        public Object visit(ASTEqualityExpression node, Object data) 
        {
            return node.childrenAccept(this, data);
        }

        public Object visit(ASTExpression node, Object data) 
        {
            return node.childrenAccept(this, data);
        }

        public Object visit(ASTFunctionInvocation node, Object data) 
        {
            return node.childrenAccept(this, data);
        }

        public Object visit(ASTLiteral node, Object data) 
        {
            return node.childrenAccept(this, data);
        }

        public Object visit(ASTMultiplyExpression node, Object data) 
        {
            return node.childrenAccept(this, data);
        }

        public Object visit(ASTOrExpression node, Object data) 
        {
            return node.childrenAccept(this, data);
        }

        public Object visit(ASTRelationalExpression node, Object data) 
        {
            return node.childrenAccept(this, data);
        }

        public Object visit(ASTUnaryExpression node, Object data) 
        {
            return node.childrenAccept(this, data);
        }

        public Object visit(ASTValue node, Object data) 
        {
            // we're only in this value expr if it contains the cursor
            if (testContainsCursor(node))
            {
                return node.childrenAccept(this, data);
            }
            
            return null;
        }

        public Object visit(ASTValuePrefix node, Object data) 
        {
            // for now, only concern ourselves with simple (identifier) prefixes
            if (!_prefixResolved
                    && node.jjtGetNumChildren() == 0
                    && node.getFirstToken().kind == JSPELParserConstants.IDENTIFIER)
            {
                _symbolPrefix = node.getFirstToken().image;
                
                if (testContainsCursor(node))
                {
                    // if the cursor is on this id, we don't need to visit
                    // further since we know both the prefix -- the id -- and
                    // the type -- it's an id completion
                    _prefixType = ContentAssistStrategy.PREFIX_TYPE_ID_COMPLETION;
                    _symbolStartPos = node.getFirstToken().beginColumn;
                    _symbolEndPos = node.getFirstToken().endColumn;
                    _prefixResolved = true;
                }
            }
            return node.childrenAccept(this, data);
        }

        public Object visit(ASTValueSuffix node, Object data) 
        {
            // for now, only deal with the simple .id suffix
            Token lastToken = node.getLastToken();
			if (node.jjtGetNumChildren() == 0)
            {
                if (!_prefixResolved
                      && node.getFirstToken().kind == JSPELParserConstants.DOT)
                {
                    if (lastToken.kind == JSPELParserConstants.IDENTIFIER)
                    {
                        if (testContainsCursor(node))
                        {
                            _prefixType = ContentAssistStrategy.PREFIX_TYPE_DOT_COMPLETION;
                            int proposalStartLength = _relativePos - lastToken.beginColumn;
                            if (proposalStartLength < 0) { // Cursor after firstToken start but before lastToken start?
                            	proposalStartLength = 0;
                            }
                            _symbolStartPos = lastToken.beginColumn;
                            _symbolEndPos = lastToken.endColumn;
                            _prefixResolved = true;
                        }
                        // only include this suffix on the path if the cursor is 
                        // further to the right.  Thus for x.^y we get a prefix "x"
                        // and for x.y.^z we get "x.y" since this the part we must
                        // resolve the prefix for
                        else
                        {
                            _symbolPrefix += node.getFirstToken().image + lastToken.image;
                        }
                    }
                    else if (lastToken == node.getFirstToken())
                    {
                        if (testCursorImmediatelyAfter(node))
                        {
                            _prefixType = ContentAssistStrategy.PREFIX_TYPE_DOT_COMPLETION;
                            _symbolStartPos = lastToken.endColumn + 1;
                            _symbolEndPos = lastToken.endColumn;
                            _prefixResolved = true;
                        }
                    }
                }

                return null;                
            }
            
            if (node.getFirstToken().kind == JSPELParserConstants.LBRACKET)
            {
                // try to support ca inside the brackets
                node.childrenAccept(this, data);
            }

            Object retValue =  node.childrenAccept(this, data);
                
            if (!_prefixResolved)
            {
                // if we haven't resolved the prefix yet, then we need
                // to append this suffix value
                _symbolPrefix += _fullText.substring(node.getFirstToken().beginColumn-1, node.getLastToken().endColumn);
            }
            
            return retValue;
        }

        public Object visit(SimpleNode node, Object data) 
        {
            return node.childrenAccept(this, data);
        }
        
        private boolean testCursorImmediatelyAfter(SimpleNode node)
        {
            return node.getLastToken().endColumn == _relativePos-1;
        }
        
        /**
         * "Containing a cursor" here is deemed to mean that current cursor
         * position as indicated by _relativePos, is either directly before, on or
         * directly after an expression.  For example, in a Value expression like
         * 
         *          x x x . y y y . z z z
         *         ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
         *         1 2 3 4 5 6 7 8 9 0 1 2
         *         
         * Position's 1-4 are on xxx, 5-8 are on yyy and 9-12 are on zzz
         * 
         * @param node
         * @return true if the node "contains the cursor" (see above)
         */
        private boolean testContainsCursor(SimpleNode node)
        {
            return (node.getFirstToken().beginColumn <= _relativePos
                    && node.getLastToken().endColumn+1 >= _relativePos);
                
        }
    }
    
    private ContentAssistParser()
    {
        // utility class; not instantiable
    }
}
