package org.apache.commons.ognl;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import org.apache.commons.ognl.enhance.ExpressionCompiler;

import java.math.BigDecimal;
import java.math.BigInteger;

import static java.lang.String.format;

/**
 * $Id$
 */
class ASTAdd
    extends NumericExpression
{
    public ASTAdd( int id )
    {
        super( id );
    }

    public ASTAdd( OgnlParser p, int id )
    {
        super( p, id );
    }

    public void jjtClose()
    {
        flattenTree();
    }

    protected Object getValueBody( OgnlContext context, Object source )
        throws OgnlException
    {
        Object result = children[0].getValue( context, source );

        for ( int i = 1; i < children.length; ++i )
        {
            result = OgnlOps.add( result, children[i].getValue( context, source ) );
        }

        return result;
    }

    public String getExpressionOperator( int index )
    {
        return "+";
    }

    boolean isWider( NodeType type, NodeType lastType )
    {
        if ( lastType == null )
        {
            return true;
        }

        // System.out.println("checking isWider(" + type.getGetterClass() + " , " + lastType.getGetterClass() + ")");

        if ( String.class.isAssignableFrom( lastType.getGetterClass() ) )
        {
            return false;
        }

        if ( String.class.isAssignableFrom( type.getGetterClass() ) )
        {
            return true;
        }

        if ( parent != null && String.class.isAssignableFrom( type.getGetterClass() ) )
        {
            return true;
        }

        if ( String.class.isAssignableFrom( lastType.getGetterClass() ) && Object.class == type.getGetterClass() )
        {
            return false;
        }

        if ( parent != null && String.class.isAssignableFrom( lastType.getGetterClass() ) )
        {
            return false;
        }
        if ( parent == null && String.class.isAssignableFrom( lastType.getGetterClass() ) )
        {
            return true;
        }
        if ( parent == null && String.class.isAssignableFrom( type.getGetterClass() ) )
        {
            return false;
        }

        if ( BigDecimal.class.isAssignableFrom( type.getGetterClass() )
            || BigInteger.class.isAssignableFrom( type.getGetterClass() ) )
        {
            return true;
        }

        if ( BigDecimal.class.isAssignableFrom( lastType.getGetterClass() )
            || BigInteger.class.isAssignableFrom( lastType.getGetterClass() ) )
        {
            return false;
        }

        if ( Double.class.isAssignableFrom( type.getGetterClass() ) )
        {
            return true;
        }

        if ( Integer.class.isAssignableFrom( type.getGetterClass() )
            && Double.class.isAssignableFrom( lastType.getGetterClass() ) )
        {
            return false;
        }

        if ( Float.class.isAssignableFrom( type.getGetterClass() )
            && Integer.class.isAssignableFrom( lastType.getGetterClass() ) )
        {
            return true;
        }

        return true;
    }

    public String toGetSourceString( OgnlContext context, Object target )
    {
        try
        {
            StringBuilder result = new StringBuilder();
            NodeType lastType = null;

            // go through once to determine the ultimate type

            if ( ( children != null ) && ( children.length > 0 ) )
            {
                Class currType = context.getCurrentType();
                Class currAccessor = context.getCurrentAccessor();

                Object cast = context.get( ExpressionCompiler.PRE_CAST );

                for ( Node aChildren : children )
                {
                    aChildren.toGetSourceString( context, target );

                    if ( NodeType.class.isInstance( aChildren ) && ( (NodeType) aChildren ).getGetterClass() != null
                        && isWider( (NodeType) aChildren, lastType ) )
                    {
                        lastType = (NodeType) aChildren;
                    }
                }

                context.put( ExpressionCompiler.PRE_CAST, cast );

                context.setCurrentType( currType );
                context.setCurrentAccessor( currAccessor );
            }

            // reset context since previous children loop would have changed it

            context.setCurrentObject( target );

            if ( ( children != null ) && ( children.length > 0 ) )
            {

                for ( int i = 0; i < children.length; ++i )
                {
                    if ( i > 0 )
                    {
                        result.append(" ").append(getExpressionOperator(i)).append(" ");
                    }

                    String expr = children[i].toGetSourceString( context, target );

                    if ( ( "null".equals( expr ) )
                        || ( !ASTConst.class.isInstance( children[i] )
                        && ( expr == null || expr.trim().isEmpty() ) ) )
                    {
                        expr = "null";
                    }

                    // System.out.println("astadd child class: " + _children[i].getClass().getName() +
                    // " and return expr: " + expr);

                    if ( ASTProperty.class.isInstance( children[i] ) )
                    {
                        expr = ExpressionCompiler.getRootExpression( children[i], context.getRoot(), context ) + expr;
                        context.setCurrentAccessor( context.getRoot().getClass() );
                    }
                    else if ( ASTMethod.class.isInstance( children[i] ) )
                    {
                        String chain = (String) context.get( "_currentChain" );
                        String rootExpr =
                            ExpressionCompiler.getRootExpression( children[i], context.getRoot(), context );

                        // System.out.println("astadd chains is >>" + chain + "<< and rootExpr is >>" + rootExpr +
                        // "<<");

                        // dirty fix for overly aggressive casting dot operations
                        if ( rootExpr.endsWith( "." ) && chain != null && chain.startsWith( ")." ) )
                        {
                            chain = chain.substring( 1 );
                        }

                        expr = rootExpr + ( chain != null ? chain + "." : "" ) + expr;
                        context.setCurrentAccessor( context.getRoot().getClass() );

                    }
                    else if ( ExpressionNode.class.isInstance( children[i] ) )
                    {
                        expr = "(" + expr + ")";
                    }
                    else if ( ( parent == null || !ASTChain.class.isInstance( parent ) )
                        && ASTChain.class.isInstance( children[i] ) )
                    {
                        String rootExpr =
                            ExpressionCompiler.getRootExpression( children[i], context.getRoot(), context );

                        if ( !ASTProperty.class.isInstance( children[i].jjtGetChild( 0 ) ) && rootExpr.endsWith( ")" )
                            && expr.startsWith( ")" ) )
                        {
                            expr = expr.substring( 1 );
                        }

                        expr = rootExpr + expr;
                        context.setCurrentAccessor( context.getRoot().getClass() );

                        String cast = (String) context.remove( ExpressionCompiler.PRE_CAST );
                        if ( cast == null )
                        {
                            cast = "";
                        }

                        expr = cast + expr;
                    }

                    // turn quoted characters into quoted strings

                    if ( context.getCurrentType() != null && context.getCurrentType() == Character.class
                        && ASTConst.class.isInstance( children[i] ) )
                    {
                        expr = expr.replace( "'", "\"" );
                        context.setCurrentType( String.class );
                    }
                    else
                    {

                        if ( !ASTVarRef.class.isAssignableFrom( children[i].getClass() )
                            && !ASTProperty.class.isInstance( children[i] )
                            && !ASTMethod.class.isInstance( children[i] )
                            && !ASTSequence.class.isInstance( children[i] )
                            && !ASTChain.class.isInstance( children[i] )
                            && !NumericExpression.class.isAssignableFrom( children[i].getClass() )
                            && !ASTStaticField.class.isInstance( children[i] )
                            && !ASTStaticMethod.class.isInstance( children[i] )
                            && !ASTTest.class.isInstance( children[i] ) )
                        {
                            if ( lastType != null && String.class.isAssignableFrom( lastType.getGetterClass() ) )
                            {
                                // System.out.println("Input expr >>" + expr + "<<");
                                expr = expr.replace( "&quot;", "\"" );
                                expr = expr.replace( "\"", "'" );
                                expr = format( "\"%s\"", expr );
                                // System.out.println("Expr now >>" + expr + "<<");
                            }
                        }
                    }

                    result.append(expr);

                    // hanlde addition for numeric types when applicable or just string concatenation

                    if ( ( lastType == null || !String.class.isAssignableFrom( lastType.getGetterClass() ) )
                        && !ASTConst.class.isAssignableFrom( children[i].getClass() )
                        && !NumericExpression.class.isAssignableFrom( children[i].getClass() ) )
                    {
                        if ( context.getCurrentType() != null
                            && Number.class.isAssignableFrom( context.getCurrentType() )
                            && !ASTMethod.class.isInstance( children[i] ) )
                        {
                            if ( ASTVarRef.class.isInstance( children[i] )
                                || ASTProperty.class.isInstance( children[i] )
                                || ASTChain.class.isInstance( children[i] ) )
                            {
                                result.append(".");
                            }

                            result.append(OgnlRuntime.getNumericValueGetter(context.getCurrentType()));
                            context.setCurrentType( OgnlRuntime.getPrimitiveWrapperClass( context.getCurrentType() ) );
                        }
                    }

                    if ( lastType != null )
                    {
                        context.setCurrentAccessor( lastType.getGetterClass() );
                    }
                }
            }

            if ( parent == null || ASTSequence.class.isAssignableFrom( parent.getClass() ) )
            {
                if ( getterClass != null && String.class.isAssignableFrom( getterClass ) )
                {
                    getterClass = Object.class;
                }
            }
            else
            {
                context.setCurrentType( getterClass );
            }

            try
            {
                Object contextObj = getValueBody( context, target );
                context.setCurrentObject( contextObj );
            }
            catch ( Throwable t )
            {
                throw OgnlOps.castToRuntime( t );
            }

            return result.toString();

        }
        catch ( Throwable t )
        {
            throw OgnlOps.castToRuntime( t );
        }
    }

    public <R, P> R accept( NodeVisitor<? extends R, ? super P> visitor, P data )
        throws OgnlException
    {
        return visitor.visit( this, data );
    }
}
