/*******************************************************************************
 * 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 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.IStructuredDocumentSymbolResolverFactory;
import org.eclipse.jst.jsf.designtime.resolver.ISymbolContextResolver;
import org.eclipse.jst.jsf.validation.internal.IJSFViewValidator.IValidationReporter;
import org.eclipse.jst.jsf.validation.internal.el.diagnostics.DiagnosticFactory;
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;


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 IValidationReporter               _reporter;

    ASTSemanticValidator(final ASTExpression expr,
            final IStructuredDocumentContext context,
            final IStructuredDocumentSymbolResolverFactory symbolResolverFactory,
            final IValidationReporter reporter)
    {
        final IWorkspaceContextResolver resolver = IStructuredDocumentContextResolverFactory.INSTANCE
                .getWorkspaceContextResolver(context);

        if (resolver != null)
        {
            _targetFile = (IFile) resolver.getResource();
        }
        else
        {
            _targetFile = null;
        }

        _expr = expr;
        _context = context;
        _symbolResolver = symbolResolverFactory.getSymbolContextResolver(context);
        _tracker = new EvaluationTracker();
        _diagnosticFactory = new DiagnosticFactory();
        _reporter = reporter;
    }

    /* (non-Javadoc)
     * @see org.eclipse.jst.jsf.validation.internal.el.IExpressionSemanticValidator#validate()
     */
    public void validate()
    {
        _expr.jjtAccept(this, _tracker);
    }

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

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

    public Object visit(final ASTChoiceExpression node, final 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;
                _reporter.report(diagnostic, offset, length);
            }

            ((EvaluationTracker)data).setType(operator.perform(choiceArg, whenTrueArg, whenFalseArg));
        }
        else
        {
            ((EvaluationTracker)data).setType(null);
        }

        return data;
    }

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

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

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

    public Object visit(final ASTLiteral node, final 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;

        final 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(final 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(final ASTMultiplyExpression node, final Object data)
    {
        performBinaryEvaluation(node, (EvaluationTracker)data);
        return data;
    }

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

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

    public Object visit(final ASTUnaryExpression node, final 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;
                        _reporter.report(diagnostic, offset, length);
                    }

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

                    Diagnostic diagnostic = 
                        _diagnosticFactory.create_CANNOT_APPLY_OPERATOR_TO_METHOD_BINDING();
                    
                    _reporter.report(diagnostic, offset, length);
                }
            }
        }

        return data;
    }

    public Object visit(final ASTValue node, final Object data) {
        final ValueExpressionTracker  tracker = new ValueExpressionTracker();

        ((EvaluationTracker)data).setValueTracker(tracker);

        node.childrenAccept(this, data);

        final 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 offset = tracker.getCurPropertySymbolOffset();
            final int length = tracker.getCurPropertySymbolLength();
            final Diagnostic diagnostic = 
                _diagnosticFactory.create_MEMBER_IS_INTERMEDIATE(
                        ((IPropertySymbol)((IObjectSymbolBasedValueType)type).getSymbol()).getName());
            _reporter.report(diagnostic, offset, length);
        }

        return data;
    }

    public Object visit(final 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 offset =
                    _context.getDocumentPosition() + token.beginColumn - 1;
                final int length = token.endColumn - token.beginColumn + 1;

                final Diagnostic diagnostic =
                    _diagnosticFactory.create_VARIABLE_NOT_FOUND(image);

                if (diagnostic.getSeverity() != Diagnostic.OK)
                {
                    _reporter.report(diagnostic, offset, length);
                }
            }
            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 offset =
                    _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);
                final Diagnostic diagnostic =
                    dotOp.validate(symbolType,
                            suffixLiteral);

                if (diagnostic.getSeverity() != Diagnostic.OK)
                {
                    _reporter.report(diagnostic, offset, length);
                    ((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(offset, 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 offset =
                        _context.getDocumentPosition() + firstToken.beginColumn - 1;
                    final int length = lastToken.endColumn - firstToken.beginColumn + 1;

                    final BracketOperator  bracketOperator = new BracketOperator(_diagnosticFactory, _targetFile);

                    final Diagnostic diagnostic =
                        bracketOperator.validate(symbolType,
                                (ValueType)subExprType);

                    if (diagnostic.getSeverity() != Diagnostic.OK)
                    {
                        _reporter.report(diagnostic, offset, length);
                        ((EvaluationTracker) data).setType(null);
                    }
                    else
                    {
                        ((EvaluationTracker) data).setType(bracketOperator.performOperation(symbolType,
                                (ValueType)subExprType));
                        tracker.setCurMemberSymbol(offset, 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(final SimpleNode node, final Object data) {
        return node.childrenAccept(this, data);
    }

    /**
     * Copies stored messages into the validation reporter
     * @param validator
     * @param reporter
     */
//    public void reportFindings(final IValidator validator, final IReporter reporter)
//    {
//        for (final IMessage message : _messages)
//        {
//            // don't report messages that have no severity.
//            if ((message.getSeverity() & IMessage.ALL_MESSAGES) != 0)
//            {
//                reporter.addMessage(validator, message);
//            }
//        }
//    }

    private void performBinaryEvaluation(final ASTOperatorExpression node, final 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;
                    _reporter.report(diagnostic, offset, length);
                }

                curType = operator.performOperation(curType, secondType);
            }
        }

        tracker.setType(curType);
    }

    private ValueType getValueTypeForBinaryOperation(final SignatureBasedType type, final 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;
            final Diagnostic diagnostic = _diagnosticFactory.create_CANNOT_APPLY_OPERATOR_TO_METHOD_BINDING();
            _reporter.report(diagnostic, offset, length);
        }

        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(final String[] args) throws IOException, ParseException
    {
        String elText = "";
        int nextCharacter;

        while(((nextCharacter = System.in.read()) != -1))
        {
            final char nextChar = (char) nextCharacter;

            if (nextChar == '\n')
            {
                final JSPELParser parser = JSPELParser.createParser(elText);
                final ASTExpression expr = parser.Expression();
                expr.dump("");

                elText = "";
            }
            else
            {
                elText += nextChar;
            }
        }
    }
}
