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 org.apache.commons.ognl.enhance.OgnlExpressionCompiler;
import org.apache.commons.ognl.enhance.OrderedReturn;
import org.apache.commons.ognl.enhance.UnsupportedCompilationException;

import java.lang.reflect.Method;

/**
 * $Id$
 */
public class ASTMethod
    extends SimpleNode
    implements OrderedReturn, NodeType
{

    private String methodName;

    private String lastExpression;

    private String coreExpression;

    private Class getterClass;

    public ASTMethod( int id )
    {
        super( id );
    }

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

    /**
     * Called from parser action.
     *
     * @param methodName sets the name of the method
     */
    public void setMethodName( String methodName )
    {
        this.methodName = methodName;
    }

    /**
     * Returns the method name that this node will call.
     *
     * @return the method name
     */
    public String getMethodName()
    {
        return methodName;
    }

    protected Object getValueBody( OgnlContext context, Object source )
        throws OgnlException
    {
        Object[] args = new Object[jjtGetNumChildren()];

        Object result, root = context.getRoot();

        for ( int i = 0; i < args.length; ++i )
        {
            args[i] = children[i].getValue( context, root );
        }

        result = OgnlRuntime.callMethod( context, source, methodName, args );

        if ( result == null )
        {
            NullHandler nullHandler = OgnlRuntime.getNullHandler( OgnlRuntime.getTargetClass( source ) );
            result = nullHandler.nullMethodResult( context, source, methodName, args );
        }

        return result;
    }

    public String getLastExpression()
    {
        return lastExpression;
    }

    public String getCoreExpression()
    {
        return coreExpression;
    }

    public Class getGetterClass()
    {
        return getterClass;
    }

    public Class getSetterClass()
    {
        return getterClass;
    }

    public String toGetSourceString( OgnlContext context, Object target )
    {
        /*
         * System.out.println("methodName is " + methodName + " for target " + target + " target class: " + (target !=
         * null ? target.getClass() : null) + " current type: " + context.getCurrentType());
         */
        if ( target == null )
        {
            throw new UnsupportedCompilationException( "Target object is null." );
        }

        String post = "";
        StringBuilder sourceStringBuilder;
        Method method;

        OgnlExpressionCompiler compiler = OgnlRuntime.getCompiler( context );
        try
        {

            method = OgnlRuntime.getMethod( context, context.getCurrentType() != null
                ? context.getCurrentType()
                : target.getClass(), methodName, children, false );
            if ( method == null )
            {
                method = OgnlRuntime.getReadMethod( target.getClass(), methodName,
                                                    children != null ? children.length : -1 );
            }

            if ( method == null )
            {
                method = OgnlRuntime.getWriteMethod( target.getClass(), methodName,
                                                     children != null ? children.length : -1 );

                if ( method != null )
                {

                    context.setCurrentType( method.getReturnType() );
                    context.setCurrentAccessor(
                        compiler.getSuperOrInterfaceClass( method, method.getDeclaringClass() ) );

                    coreExpression = toSetSourceString( context, target );
                    if ( coreExpression == null || coreExpression.length() < 1 )
                    {
                        throw new UnsupportedCompilationException( "can't find suitable getter method" );
                    }

                    coreExpression += ";";
                    lastExpression = "null";

                    return coreExpression;
                }

                return "";
            }
            getterClass = method.getReturnType();

            // TODO: This is a hacky workaround until javassist supports varargs method invocations
            boolean varArgs = method.isVarArgs();

            if ( varArgs )
            {
                throw new UnsupportedCompilationException(
                    "Javassist does not currently support varargs method calls" );
            }

            sourceStringBuilder = new StringBuilder().append( "." ).append( method.getName() ).append( "(" );

            if ( ( children != null ) && ( children.length > 0 ) )
            {
                Class[] parms = method.getParameterTypes();
                String prevCast = (String) context.remove( ExpressionCompiler.PRE_CAST );
                /*
                 * System.out.println("before children methodName is " + methodName + " for target " + target +
                 * " target class: " + (target != null ? target.getClass() : null) + " current type: " +
                 * context.getCurrentType() + " and previous type: " + context.getPreviousType());
                 */

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

                    Class prevType = context.getCurrentType();

                    Object root = context.getRoot();
                    context.setCurrentObject( root );
                    context.setCurrentType( root != null ? root.getClass() : null );
                    context.setCurrentAccessor( null );
                    context.setPreviousType( null );

                    Node child = children[i];

                    String parmString = ASTMethodUtil.getParmString( context, root, child, prevType );

                    Class valueClass = ASTMethodUtil.getValueClass( context, root, child );

                    if ( ( !varArgs || varArgs && ( i + 1 ) < parms.length ) && valueClass != parms[i] )
                    {
                        parmString = ASTMethodUtil.getParmString( context, parms[i], parmString, child, valueClass,
                                                                  ".class, true)" );
                    }

                    sourceStringBuilder.append( parmString );
                }

                if ( prevCast != null )
                {
                    context.put( ExpressionCompiler.PRE_CAST, prevCast );
                }
            }

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

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

        sourceStringBuilder.append( ")" ).append( post );

        if ( method.getReturnType() == void.class )
        {
            coreExpression = sourceStringBuilder.toString() + ";";
            lastExpression = "null";
        }

        context.setCurrentType( method.getReturnType() );
        context.setCurrentAccessor( compiler.getSuperOrInterfaceClass( method, method.getDeclaringClass() ) );

        return sourceStringBuilder.toString();
    }

    public String toSetSourceString( OgnlContext context, Object target )
    {
        /*
         * System.out.println("current type: " + context.getCurrentType() + " target:" + target + " " +
         * context.getCurrentObject() + " last child? " + lastChild(context));
         */
        Method method =
            OgnlRuntime.getWriteMethod( context.getCurrentType() != null ? context.getCurrentType() : target.getClass(),
                                        methodName, children != null ? children.length : -1 );
        if ( method == null )
        {
            throw new UnsupportedCompilationException(
                "Unable to determine setter method generation for " + methodName );
        }

        String post = "";
        String result = "." + method.getName() + "(";

        if ( method.getReturnType() != void.class && method.getReturnType().isPrimitive() && ( parent == null
            || !ASTTest.class.isInstance( parent ) ) )
        {
            Class wrapper = OgnlRuntime.getPrimitiveWrapperClass( method.getReturnType() );

            ExpressionCompiler.addCastString( context, "new " + wrapper.getName() + "(" );
            post = ")";
            getterClass = wrapper;
        }

        boolean varArgs = method.isVarArgs();

        if ( varArgs )
        {
            throw new UnsupportedCompilationException( "Javassist does not currently support varargs method calls" );
        }

        OgnlExpressionCompiler compiler = OgnlRuntime.getCompiler( context );
        try
        {
            /*
             * if (lastChild(context) && method.getParameterTypes().length > 0 && _children.length <= 0) throw new
             * UnsupportedCompilationException("Unable to determine setter method generation for " + method);
             */

            if ( ( children != null ) && ( children.length > 0 ) )
            {
                Class[] parms = method.getParameterTypes();
                String prevCast = (String) context.remove( ExpressionCompiler.PRE_CAST );

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

                    Class prevType = context.getCurrentType();

                    context.setCurrentObject( context.getRoot() );
                    context.setCurrentType( context.getRoot() != null ? context.getRoot().getClass() : null );
                    context.setCurrentAccessor( null );
                    context.setPreviousType( null );

                    Node child = children[i];
                    Object value = child.getValue( context, context.getRoot() );
                    String parmString = child.toSetSourceString( context, context.getRoot() );

                    if ( context.getCurrentType() == Void.TYPE || context.getCurrentType() == void.class )
                    {
                        throw new UnsupportedCompilationException( "Method argument can't be a void type." );
                    }

                    if ( parmString == null || parmString.trim().length() < 1 )
                    {
                        if ( ASTProperty.class.isInstance( child ) || ASTMethod.class.isInstance( child )
                            || ASTStaticMethod.class.isInstance( child ) || ASTChain.class.isInstance( child ) )
                        {
                            throw new UnsupportedCompilationException(
                                "ASTMethod setter child returned null from a sub property expression." );
                        }
                        parmString = "null";
                    }

                    // to undo type setting of constants when used as method parameters
                    if ( ASTConst.class.isInstance( child ) )
                    {
                        context.setCurrentType( prevType );
                    }

                    parmString = ExpressionCompiler.getRootExpression( child, context.getRoot(), context ) + parmString;

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

                    if ( cast == null )
                    {
                        cast = "";
                    }

                    parmString = cast + parmString;

                    Class valueClass = value != null ? value.getClass() : null;
                    if ( NodeType.class.isAssignableFrom( child.getClass() ) )
                    {
                        valueClass = ( (NodeType) child ).getGetterClass();
                    }

                    if ( valueClass != parms[i] )
                    {
                        parmString =
                            ASTMethodUtil.getParmString( context, parms[i], parmString, child, valueClass, ".class)" );
                    }

                    result += parmString;
                }

                if ( prevCast != null )
                {
                    context.put( ExpressionCompiler.PRE_CAST, prevCast );
                }
            }

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

        try
        {
            Object contextObj = getValueBody( context, target );
            context.setCurrentObject( contextObj );
        }
        catch ( Throwable t )
        {
            // ignore
        }

        context.setCurrentType( method.getReturnType() );
        context.setCurrentAccessor( compiler.getSuperOrInterfaceClass( method, method.getDeclaringClass() ) );

        return result + ")" + post;
    }

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