/*******************************************************************************
 * 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.ELValidationPreferences;
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<IMessage>					_messages;
	private final EvaluationTracker                 _tracker;
	private final DiagnosticFactory                 _diagnosticFactory;
	private final ELValidationPreferences           _prefs;
    private boolean                                 _validatorHasBeenCalled; //=false
    
	ASTSemanticValidator(ASTExpression expr, IStructuredDocumentContext context, ELValidationPreferences prefs)
	{
		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<IMessage>();
        _tracker = new EvaluationTracker();
        _diagnosticFactory = new DiagnosticFactory();
        _prefs = prefs;
	}
	
	/* (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(_diagnosticFactory);
            
            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, _prefs);
                _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, _diagnosticFactory);
                    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,_prefs);
                        _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,_prefs));
                }
            }
        }

        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_IS_INTERMEDIATE(
                        ((IPropertySymbol)((IObjectSymbolBasedValueType)type).getSymbol()).getName())
                        , problemStartOffset, length, _targetFile, _prefs));
        }
            
        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;
 
                final Diagnostic diag =  
                    _diagnosticFactory.create_VARIABLE_NOT_FOUND(image);
                
                if (diag.getSeverity() != Diagnostic.OK)
                {
    				_messages.add(
    				    ValidationMessageFactory.createFromDiagnostic(diag, 
    	                        problemStartOffset, length, _targetFile, _prefs));
                }
			}
			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(_diagnosticFactory, _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, _prefs));
                    ((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(_diagnosticFactory, _targetFile);
                    
                    final Diagnostic diag = 
                        bracketOperator.validate(symbolType, 
                                            (ValueType)subExprType);

                    if (diag.getSeverity() != Diagnostic.OK)
                    {
                        _messages.add(ValidationMessageFactory.createFromDiagnostic(
                                diag, 
                                startOffset, length, _targetFile, _prefs));
                        ((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<IMessage> it = _messages.iterator(); it.hasNext();)
		{
		    IMessage message = it.next();
		    
		    // don't report messages that have no severity.
		    if ((message.getSeverity() & IMessage.ALL_MESSAGES) != 0)
		    {
		        reporter.addMessage(validator, message);
		    }
		}
	}
    
    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), _diagnosticFactory, _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, _prefs);
                    _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, _prefs));
        }

        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;
            }   
        }
    }
}
