/*******************************************************************************
 * 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.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()))
        {
            return new IdCompletionStrategy("", "");
        }
        
        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.getPrefix();
        }
        catch (ParseException pe)
        {
            // TODO: handle parser by using current and expected tokens
        }
        
        return null;
    }
    
    private static class PrefixVisitor implements JSPELParserVisitor
    {
        private final int       _relativePos;
        private final String    _fullText;
        
        private String          _curPrefix; // = null; initialized as tree is visited
        private int             _prefixType;
        private boolean         _prefixResolved;  // = false; set to true when the prefix is resolved
        private String          _proposalStart = "";
        
        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(_curPrefix, _proposalStart);
                    
                    case ContentAssistStrategy.PREFIX_TYPE_ID_COMPLETION:
                        return new IdCompletionStrategy(_curPrefix, _proposalStart);
                    
                    case ContentAssistStrategy.PREFIX_TYPE_EMPTY_EXPRESSION:
                        return new IdCompletionStrategy("", _proposalStart);
                        
                    default:
                        // do nothing; fall-through to return null
                }
            }

            return null;
        }
        
        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)
            {
                _curPrefix = 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;
                    int proposalLength = _relativePos - node.getFirstToken().beginColumn;
					_proposalStart = node.getFirstToken().image.substring(0, proposalLength);
                    _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;
                            }
							_proposalStart = lastToken.image.substring(0, proposalStartLength);
                            _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
                        {
                            _curPrefix += node.getFirstToken().image + lastToken.image;
                        }
                    }
                    else if (lastToken == node.getFirstToken())
                    {
                        if (testCursorImmediatelyAfter(node))
                        {
                            _prefixType = ContentAssistStrategy.PREFIX_TYPE_DOT_COMPLETION;
                            _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
                _curPrefix += _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
    }
}
