/*******************************************************************************
 * 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.validation.internal.el;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.jst.jsf.common.internal.types.BooleanLiteralType;
import org.eclipse.jst.jsf.common.internal.types.FloatLiteralType;
import org.eclipse.jst.jsf.common.internal.types.IntegerLiteralType;
import org.eclipse.jst.jsf.common.internal.types.LiteralType;
import org.eclipse.jst.jsf.common.internal.types.MethodType;
import org.eclipse.jst.jsf.common.internal.types.NullLiteralType;
import org.eclipse.jst.jsf.common.internal.types.SignatureBasedType;
import org.eclipse.jst.jsf.common.internal.types.StringLiteralType;
import org.eclipse.jst.jsf.common.internal.types.ValueType;
import org.eclipse.jst.jsf.context.resolver.structureddocument.IStructuredDocumentContextResolverFactory;
import org.eclipse.jst.jsf.context.resolver.structureddocument.IWorkspaceContextResolver;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext;
import org.eclipse.jst.jsf.context.symbol.IInstanceSymbol;
import org.eclipse.jst.jsf.context.symbol.IPropertySymbol;
import org.eclipse.jst.jsf.context.symbol.ISymbol;
import org.eclipse.jst.jsf.context.symbol.internal.util.IObjectSymbolBasedValueType;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.designtime.resolver.ISymbolContextResolver;
import org.eclipse.jst.jsf.designtime.resolver.StructuredDocumentSymbolResolverFactory;
import org.eclipse.jst.jsf.validation.internal.el.diagnostics.DiagnosticFactory;
import org.eclipse.jst.jsf.validation.internal.el.diagnostics.ValidationMessageFactory;
import org.eclipse.jst.jsf.validation.internal.el.operators.BinaryOperator;
import org.eclipse.jst.jsf.validation.internal.el.operators.BracketOperator;
import org.eclipse.jst.jsf.validation.internal.el.operators.DotOperator;
import org.eclipse.jst.jsf.validation.internal.el.operators.TernaryChoiceOperator;
import org.eclipse.jst.jsf.validation.internal.el.operators.UnaryOperator;
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.ASTOperatorExpression;
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;
import org.eclipse.wst.validation.internal.core.Message;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;
import org.eclipse.wst.validation.internal.provisional.core.IValidator;


class ASTSemanticValidator implements JSPELParserVisitor, IExpressionSemanticValidator
{
	private final IFile								_targetFile;
	private final ASTExpression 					_expr;
	private final IStructuredDocumentContext		_context;
	private final ISymbolContextResolver			_symbolResolver;
	private final List								_messages;
	private final EvaluationTracker                 _tracker;
    private boolean                                 _validatorHasBeenCalled; //=false
    
	ASTSemanticValidator(ASTExpression expr, IStructuredDocumentContext context)
	{
		final IWorkspaceContextResolver resolver = 
            IStructuredDocumentContextResolverFactory.
                INSTANCE.getWorkspaceContextResolver(context);
        
		if (resolver != null)
		{
			_targetFile = (IFile) resolver.getResource();
		}
		else
		{
			_targetFile = null;
		}
        
		_expr = expr;
		_context = context;
		_symbolResolver = StructuredDocumentSymbolResolverFactory.getInstance().getSymbolContextResolver(_context);
		_messages = new ArrayList();
        _tracker = new EvaluationTracker();
	}
	
	/* (non-Javadoc)
     * @see org.eclipse.jst.jsf.validation.internal.el.IExpressionSemanticValidator#validate()
     */
	public void validate()
	{
		_expr.jjtAccept(this, _tracker);
        _validatorHasBeenCalled = true;
	}
	
	public Object visit(ASTAddExpression node, Object data) 
	{
        performBinaryEvaluation(node, (EvaluationTracker)data);
        return data;
	}

	public Object visit(ASTAndExpression node, Object data) 
	{
        performBinaryEvaluation(node, (EvaluationTracker)data);
        return data;
	}

	public Object visit(ASTChoiceExpression node, Object data) 
    {
        if (node.jjtGetNumChildren() != 3)
        {
            throw new AssertionError("Binary operators should always have two sub-expressions");
        }
        
        // evaluate choice argument
        node.jjtGetChild(0).jjtAccept(this, data);
        final ValueType choiceArg = ((EvaluationTracker)data).getValueType();
        // evaluate when true argument
        node.jjtGetChild(1).jjtAccept(this, data);
        final ValueType whenTrueArg = ((EvaluationTracker)data).getValueType();
        //evaluate when false argument
        node.jjtGetChild(2).jjtAccept(this, data);
        final ValueType whenFalseArg = ((EvaluationTracker)data).getValueType();
        
        
        if (choiceArg != null && whenTrueArg != null && whenFalseArg != null)
        {
            final TernaryChoiceOperator operator = 
                new TernaryChoiceOperator();
            
            final Diagnostic diagnostic = 
                operator.validate(choiceArg/* whenTrueArg, whenFalseArg*/);
            
            if (diagnostic.getSeverity() != Diagnostic.OK)
            {
                final Token firstToken = node.getFirstToken();
                final int offset = _context.getDocumentPosition() + firstToken.beginColumn - 1;
                final int length = node.getLastToken().endColumn - firstToken.beginColumn+1;
                final Message message = 
                    ValidationMessageFactory.createFromDiagnostic(diagnostic, 
                                                   offset, length, _targetFile);
                _messages.add(message);
            }
            
            ((EvaluationTracker)data).setType(operator.perform(choiceArg, whenTrueArg, whenFalseArg));
        }
        else
        {
            ((EvaluationTracker)data).setType(null);
        }

        return data;
	}

	public Object visit(ASTEqualityExpression node, Object data) 
    {
        performBinaryEvaluation(node, (EvaluationTracker)data);
        return data;
    }

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

	public Object visit(ASTFunctionInvocation node, Object data) 
    {
	    // when we see a function invocation, null the type
        // we do not validate function invocations currently
        Object retVal = node.childrenAccept(this, data);
        ((EvaluationTracker)data).setType(null);
        return retVal;
	}

	public Object visit(ASTLiteral node, Object data) 
    {
        // note, there is an implicit assumption here that literals
        // are all terminals (leafs in the tree)
        if (node.jjtGetNumChildren() > 0)
        {
            throw new AssertionError("Literals should be terminal");
        }
        
        LiteralType type = null;
        
        Token  literalToken = node.getFirstToken();
        
        switch (literalToken.kind)
        {
            case JSPELParserConstants.STRING_LITERAL:
                type = new StringLiteralType(stripQuotes(literalToken.image));
            break;
            
            case JSPELParserConstants.INTEGER_LITERAL:
                type = new IntegerLiteralType(Long.parseLong(literalToken.image));
            break;
        
            case JSPELParserConstants.FLOATING_POINT_LITERAL:
                type = new FloatLiteralType(Double.parseDouble(literalToken.image));
            break;
            
            case JSPELParserConstants.FALSE:
                type = BooleanLiteralType.FALSE;
            break;
            
            case JSPELParserConstants.TRUE:
                type = BooleanLiteralType.TRUE;
            break;
            
            case JSPELParserConstants.NULL:
                type = NullLiteralType.SINGLETON;
            break;
            
            default:
                JSFCorePlugin.log("Unknown EL literal: " +literalToken.toString(), new Throwable("This throwable simply used to mark a stack trace"));
        }

        ((EvaluationTracker)data).setType(type);
        return data;
	}

    private String stripQuotes(String stringLiteral)
    {
        if (stringLiteral.startsWith("'")
                || stringLiteral.startsWith("\""))
                        
        {
            if (stringLiteral.length() > 2)
            {
                // take 'literal' -> literal
                return stringLiteral.substring(1, stringLiteral.length()-1);
            }
            // if only two characters, then the empty string
            return "";
        }
        
        return stringLiteral;
    }
    
	public Object visit(ASTMultiplyExpression node, Object data) 
    {
        performBinaryEvaluation(node, (EvaluationTracker)data);
        return data;
	}

	public Object visit(ASTOrExpression node, Object data) 
    {
	    performBinaryEvaluation(node, (EvaluationTracker)data);
        return data;
	}

	public Object visit(ASTRelationalExpression node, Object data) 
    {
        performBinaryEvaluation(node, (EvaluationTracker)data);
        return data;
	}

	public Object visit(ASTUnaryExpression node, Object data) 
    {
        // assertion here is that this expression decomposes:
        // UnaryExpr -> Value
        // UnaryExpr -> UnaryOp UnaryExpression
        // since UnaryOp is a terminal (-,!,not,empty) node will
        // always have exactly one child
        node.childrenAccept(this, data);
        final SignatureBasedType type = ((EvaluationTracker)data).getType();
        
        if (type != null)
        {
            final Token  firstToken = node.getFirstToken();
            if (UnaryOperator.isUnaryOperator(firstToken))
            {
                if (type instanceof ValueType)
                {
                    final UnaryOperator unaryOp = UnaryOperator.createUnaryOperator(firstToken);
                    final Diagnostic diagnostic = unaryOp.validate((ValueType)type);
                    
                    if (diagnostic.getSeverity() != Diagnostic.OK)
                    {
                        final int offset = _context.getDocumentPosition() + firstToken.beginColumn - 1;
                        final int length = node.getLastToken().endColumn - firstToken.beginColumn+1;
                        final Message message = 
                            ValidationMessageFactory.createFromDiagnostic(diagnostic, offset, length, _targetFile);
                        _messages.add(message);
                    }
   
                    ((EvaluationTracker)data).
                            setType(unaryOp.performOperation ((ValueType)type));
                }
                // cannot apply operations to method bindings
                else
                {
                    final int offset = _context.getDocumentPosition() + 
                                    firstToken.beginColumn - 1;
                    final int length = node.getLastToken().endColumn - 
                                        firstToken.beginColumn+1;
                    
                    _messages.add(ValidationMessageFactory.
                            createFromDiagnostic(DiagnosticFactory.create_CANNOT_APPLY_OPERATOR_TO_METHOD_BINDING(),
                                    offset, length, _targetFile));
                }
            }
        }

        return data;
	}

	public Object visit(ASTValue node, final Object data) {
        ValueExpressionTracker  tracker = new ValueExpressionTracker();
        
        ((EvaluationTracker)data).setValueTracker(tracker);
        
		node.childrenAccept(this, data);
        
        SignatureBasedType type = ((EvaluationTracker)data).getType();
        
        // now check the tracker.  If the last property in the expression
        // is non-null (i.e. the value has one or more suffices) then we
        // to very the leaf node (i.e. 'z' in #{x.y.z}) is more than just
        // an intermediate value used to get to other properties
        if (type instanceof IObjectSymbolBasedValueType
                && ((IObjectSymbolBasedValueType)type).getSymbol() instanceof IPropertySymbol
                && ((IPropertySymbol)((IObjectSymbolBasedValueType)type).getSymbol()).isIntermediate())
        {
            final int problemStartOffset = tracker.getCurPropertySymbolOffset();
            final int length = tracker.getCurPropertySymbolLength();
            _messages.add(ValidationMessageFactory.createFromDiagnostic(
                    DiagnosticFactory.create_MEMBER_NOT_FOUND(
                        ((IPropertySymbol)((IObjectSymbolBasedValueType)type).getSymbol()).getName()
                        , tracker.getRootSymbolName())
                        , problemStartOffset, length, _targetFile));
        }
            
        return data;
	}

	public Object visit(ASTValuePrefix node, final Object data) 
    {
		if (node.jjtGetNumChildren() == 0)
		{
			final Token token = node.getFirstToken();
			final String image = token.image;

			final ISymbol symbol = _symbolResolver.getVariable(image);

			if (symbol == null)
			{
                final int problemStartOffset = 
                    _context.getDocumentPosition() + token.beginColumn - 1;
                final int length = token.endColumn - token.beginColumn + 1;
 
				_messages.add(ValidationMessageFactory.createFromDiagnostic(
                        DiagnosticFactory.create_VARIABLE_NOT_FOUND(image), 
                        problemStartOffset, length, _targetFile));
			}
			else if (symbol instanceof IInstanceSymbol)
			{
                final IObjectSymbolBasedValueType symbolType =
                    IObjectSymbolBasedValueType.getInstance(symbol);
                ((EvaluationTracker) data).setType(symbolType);
			}
		}

		return node.childrenAccept(this, data);
	}

	public Object visit(final ASTValueSuffix node, final Object data) 
    {
        final ValueExpressionTracker tracker = ((EvaluationTracker) data).getValueTracker();
        final SignatureBasedType type = ((EvaluationTracker) data).getType();
        
        if (type instanceof IObjectSymbolBasedValueType)
        {
            final IObjectSymbolBasedValueType symbolType = 
                (IObjectSymbolBasedValueType) type;
    		final Token firstToken = node.getFirstToken();
    
    		if (node.jjtGetNumChildren() == 0
    				&& firstToken.kind == JSPELParserConstants.DOT)
    		{
    			final Token dotId = node.getLastToken();
    
                final int startOffset = 
                    _context.getDocumentPosition() + dotId.beginColumn - 1;
                final int length = dotId.endColumn - dotId.beginColumn + 1;

                final DotOperator dotOp = new DotOperator(_targetFile);

                final StringLiteralType  suffixLiteral = new StringLiteralType(dotId.image);
                Diagnostic diag = 
                    dotOp.validate(symbolType, 
                                        suffixLiteral);
                
			    if (diag.getSeverity() != Diagnostic.OK)
			    {
			        _messages.add(ValidationMessageFactory.createFromDiagnostic(
                         diag, startOffset, length, _targetFile));
                    ((EvaluationTracker) data).setType(null);
                }
                else
                {
//                    // if the base (value-a) is a map, then using the bracket value-a['y'] type
//                    // syntax is recommended.  Note that we do this here instead of 
//                    // DotOperator so that we don't tie the default property resolver
//                    // behaviour to that operator class.  If someone changes the rules
//                    // of how the prop resolver interprets the base, then they may want to
//                    // write their own validator that doesn't do this
//                    if (symbolType.getSymbol().supportsCoercion(TypeConstants.TYPE_MAP))
//                    {
//                        _messages.add(ValidationMessageFactory.createFromDiagnostic(
//                                DiagnosticFactory.create_BINARY_OP_DOT_WITH_VALUEA_MAP_SHOULD_USE_ARRAY
//                                    (symbolType.getSymbol().getName(), dotId.image), 
//                                        startOffset, length, _targetFile));
//                    }
                    
                    ((EvaluationTracker) data).setType(dotOp.performOperation(symbolType, 
                            suffixLiteral));
                    tracker.setCurMemberSymbol(startOffset, length);
                }
                
                // we finished with the single dot suffix here
                return data;
    		}
            else if (firstToken.kind == JSPELParserConstants.LBRACKET)
            {
                final EvaluationTracker subExprTracker = new EvaluationTracker();
                node.childrenAccept(this, subExprTracker);

                final SignatureBasedType subExprType = subExprTracker.getType();

                if (subExprType instanceof ValueType)
                {
                    final Token lastToken = node.getLastToken();
                    final int startOffset = 
                        _context.getDocumentPosition() + firstToken.beginColumn - 1;
                    final int length = lastToken.endColumn - firstToken.beginColumn + 1;

                    final BracketOperator  bracketOperator = new BracketOperator(_targetFile);
                    
                    final Diagnostic diag = 
                        bracketOperator.validate(symbolType, 
                                            (ValueType)subExprType);

                    if (diag.getSeverity() != Diagnostic.OK)
                    {
                        _messages.add(ValidationMessageFactory.createFromDiagnostic(
                                diag, 
                                startOffset, length, _targetFile));
                        ((EvaluationTracker) data).setType(null);
                    }
                    else
                    {
                        ((EvaluationTracker) data).setType(bracketOperator.performOperation(symbolType, 
                                (ValueType)subExprType));
                        tracker.setCurMemberSymbol(startOffset, length);
                    }
                }
                // we are finished with the bracketed suffix at this point.
                return data;
            }
        }
        
        // don't bother to accept children, since if we haven't done
        // something above, there's not much sensible we can do with it
        // clear the type first though
        ((EvaluationTracker) data).setType(null);
		return data; //node.childrenAccept(this, data);
	}

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

	/**
	 * Copies stored messages into the validation reporter 
	 * @param validator
	 * @param reporter
	 */
	public void reportFindings(IValidator validator, IReporter reporter)
	{
		for (final Iterator it = _messages.iterator(); it.hasNext();)
		{
			reporter.addMessage(validator, (IMessage) it.next());
		}
	}
    
    private void performBinaryEvaluation(ASTOperatorExpression node, EvaluationTracker tracker)
    {
        if (node.jjtGetNumChildren() < 2)
        {
            throw new AssertionError("Binary operators should always have at least two sub-expressions");
        }
        else if (node.getOperatorTokens().size() != node.jjtGetNumChildren()-1)
        {
            throw new AssertionError("Binary operators should always have one operator token less than number of sub-expressions");
        }
        
        // evaluate left-most argument
        node.jjtGetChild(0).jjtAccept(this, tracker);
        
        ValueType curType = getValueTypeForBinaryOperation(tracker.getType(), (SimpleNode) node.jjtGetChild(0)); 
            
        for (int child = 1; child < node.jjtGetNumChildren(); child++)
        {
            // evaluate next argument running left-to-right
            node.jjtGetChild(child).jjtAccept(this, tracker);
            final ValueType secondType = 
                getValueTypeForBinaryOperation(tracker.getType(), (SimpleNode) node.jjtGetChild(child));
            
            if (curType != null && secondType != null)
            {
                final BinaryOperator operator = 
                    BinaryOperator.getBinaryOperator((Token)node.getOperatorTokens().get(child-1), _context);
                
                final Diagnostic diagnostic = operator.validate(curType, secondType);
                
                if (diagnostic.getSeverity() != Diagnostic.OK)
                {
                    final Token firstToken = node.getFirstToken();
                    final int offset = _context.getDocumentPosition() + firstToken.beginColumn - 1;
                    final int length = node.getLastToken().endColumn - firstToken.beginColumn+1;
                    final Message message = 
                        ValidationMessageFactory.createFromDiagnostic
                                (diagnostic, offset, length, _targetFile);
                    _messages.add(message);
                }
                
                curType = operator.performOperation(curType, secondType);
            }
        }
        
        tracker.setType(curType);
    }

    private ValueType getValueTypeForBinaryOperation(SignatureBasedType type, SimpleNode node)
    {
        if (type instanceof ValueType)
        {
            return (ValueType) type;
        }
        else if (type instanceof MethodType)
        {
            final int offset = _context.getDocumentPosition() + node.getFirstToken().beginColumn - 1;
            final int length = node.getLastToken().endColumn - node.getFirstToken().beginColumn+1;
            
            _messages.add(ValidationMessageFactory.createFromDiagnostic
                    (DiagnosticFactory.create_CANNOT_APPLY_OPERATOR_TO_METHOD_BINDING(), 
                            offset, length, _targetFile));
        }

        return null;
    }
    
	/* (non-Javadoc)
     * @see org.eclipse.jst.jsf.validation.internal.el.IExpressionSemanticValidator#getMessages()
     */
	public List getMessages()
	{
	    if (!_validatorHasBeenCalled)
        {
	        throw new AssertionError("Should not call getMessages before validate has been called");
        }
		return _messages;
	}
    
    /* (non-Javadoc)
     * @see org.eclipse.jst.jsf.validation.internal.el.IExpressionSemanticValidator#getExpressionType()
     */
    public SignatureBasedType getExpressionType()
    {
        return _tracker.getType();
    }
    
    /**
     * @param args
     * @throws IOException
     * @throws ParseException 
     */
    public static void main(String[] args) throws IOException, ParseException
    {
        String elText = "";
        int nextCharacter;
        
        while(((nextCharacter = System.in.read()) != -1))
        {
            char nextChar = (char) nextCharacter;
            
            if (nextChar == '\n')
            {
                JSPELParser parser = JSPELParser.createParser(elText);
                ASTExpression expr = parser.Expression();
                expr.dump("");
                
                elText = "";
            }
            else
            {
                elText += nextChar;
            }   
        }
    }
}
