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.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.util.List;

/**
 * $Id$
 */
public class ASTCtor
    extends SimpleNode
{

    private String className;

    private boolean isArray;

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

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

    /** Called from parser action. */
    void setClassName( String className )
    {
        this.className = className;
    }

    /**
     * Get the class name for this constructor.
     *
     * @return the class name.
     * @since 4.0
     */
    String getClassName()
    {
        return className;
    }


    void setArray( boolean value )
    {
        isArray = value;
    }

    public boolean isArray()
    {
        return isArray;
    }

    protected Object getValueBody( OgnlContext context, Object source )
        throws OgnlException
    {
        Object result, root = context.getRoot();
        int count = jjtGetNumChildren();
        Object[] args = new Object[count];

        for ( int i = 0; i < count; ++i )
        {
            args[i] = children[i].getValue( context, root );
        }
        if ( isArray )
        {
            if ( args.length != 1 ) {
                throw new OgnlException( "only expect array size or fixed initializer list" );
            }
            try
            {
                Class componentClass = OgnlRuntime.classForName( context, className );
                List sourceList = null;
                int size;

                if ( args[0] instanceof List )
                {
                    sourceList = (List) args[0];
                    size = sourceList.size();
                }
                else
                {
                    size = (int) OgnlOps.longValue( args[0] );
                }
                result = Array.newInstance( componentClass, size );
                if ( sourceList != null )
                {
                    TypeConverter converter = context.getTypeConverter();

                    for ( int i = 0, icount = sourceList.size(); i < icount; i++ )
                    {
                        Object o = sourceList.get( i );

                        if ( ( o == null ) || componentClass.isInstance( o ) )
                        {
                            Array.set( result, i, o );
                        }
                        else
                        {
                            Array.set( result, i,
                                       converter.convertValue( context, null, null, null, o, componentClass ) );
                        }
                    }
                }
            }
            catch ( ClassNotFoundException ex )
            {
                throw new OgnlException( "array component class '" + className + "' not found", ex );
            }
        }
        else
        {
            result = OgnlRuntime.callConstructor( context, className, args );
        }

        return result;
    }


    public String toGetSourceString( OgnlContext context, Object target )
    {
        StringBuilder result = new StringBuilder("new " + className);

        Class clazz = null;
        Object ctorValue = null;
        try
        {

            clazz = OgnlRuntime.classForName( context, className );

            ctorValue = this.getValueBody( context, target );
            context.setCurrentObject( ctorValue );

            if ( ctorValue != null )
            {

                context.setCurrentType( ctorValue.getClass() );
                context.setCurrentAccessor( ctorValue.getClass() );
            }

            if ( isArray )
            {
                context.put( "_ctorClass", clazz );
            }
        }
        catch ( Throwable t )
        {
            throw OgnlOps.castToRuntime( t );
        }

        try
        {

            if ( isArray )
            {
                if ( children[0] instanceof ASTConst )
                {

                    result.append("[").append(children[0].toGetSourceString(context, target)).append("]");
                }
                else if ( ASTProperty.class.isInstance( children[0] ) )
                {

                    result.append("[").append(ExpressionCompiler.getRootExpression(children[0], target, context)).append(children[0].toGetSourceString(context, target)).append("]");
                }
                else if ( ASTChain.class.isInstance( children[0] ) )
                {

                    result.append("[").append(children[0].toGetSourceString(context, target)).append("]");
                }
                else
                {

                    result.append("[] ").append(children[0].toGetSourceString(context, target));
                }

            }
            else
            {
                result.append("(");

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

                    Object[] values = new Object[children.length];
                    String[] expressions = new String[children.length];
                    Class[] types = new Class[children.length];

                    // first populate arrays with child values

                    for ( int i = 0; i < children.length; i++ )
                    {

                        Object objValue = children[i].getValue( context, context.getRoot() );
                        String value = children[i].toGetSourceString( context, target );

                        if ( !ASTRootVarRef.class.isInstance( children[i] ) )
                        {
                            value = ExpressionCompiler.getRootExpression( children[i], target, context ) + value;
                        }

                        String cast = "";
                        if ( ExpressionCompiler.shouldCast( children[i] ) )
                        {

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

                        if ( !ASTConst.class.isInstance( children[i] ) )
                        {
                            value = cast + value;
                        }

                        values[i] = objValue;
                        expressions[i] = value;
                        types[i] = context.getCurrentType();
                    }

                    // now try and find a matching constructor

                    Constructor[] cons = clazz.getConstructors();
                    Constructor ctor = null;
                    Class[] ctorParamTypes = null;

                    for ( int i = 0; i < cons.length; i++ )
                    {
                        Class[] ctorTypes = cons[i].getParameterTypes();

                        if ( OgnlRuntime.areArgsCompatible( values, ctorTypes )
                            && ( ctor == null || OgnlRuntime.isMoreSpecific( ctorTypes, ctorParamTypes ) ) )
                        {
                            ctor = cons[i];
                            ctorParamTypes = ctorTypes;
                        }
                    }

                    if ( ctor == null )
                    {
                        ctor =
                            OgnlRuntime.getConvertedConstructorAndArgs( context, clazz,
                                                                        OgnlRuntime.getConstructors( clazz ), values,
                                                                        new Object[values.length] );
                    }

                    if ( ctor == null )
                    {
                        throw new NoSuchMethodException(
                            "Unable to find constructor appropriate for arguments in class: " + clazz );
                    }
                    ctorParamTypes = ctor.getParameterTypes();

                    // now loop over child values again and build up the actual source string

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

                        String value = expressions[i];

                        if ( types[i].isPrimitive() )
                        {

                            String literal = OgnlRuntime.getNumericLiteral( types[i] );
                            if ( literal != null )
                            {
                                value += literal;
                            }
                        }

                        if ( ctorParamTypes[i] != types[i] )
                        {

                            if ( values[i] != null && !types[i].isPrimitive() && !values[i].getClass().isArray()
                                && !ASTConst.class.isInstance( children[i] ) )
                            {

                                value =
                                    "(" + OgnlRuntime.getCompiler( context ).getInterfaceClass( values[i].getClass() ).getName()
                                        + ")" + value;
                            }
                            else if ( !ASTConst.class.isInstance( children[i] )
                                || ( ASTConst.class.isInstance( children[i] ) && !types[i].isPrimitive() ) )
                            {

                                if ( !types[i].isArray() && types[i].isPrimitive() && !ctorParamTypes[i].isPrimitive() )
                                {
                                    value =
                                        "new "
                                            + ExpressionCompiler.getCastString(
                                                OgnlRuntime.getPrimitiveWrapperClass( types[i] ) )
                                            + "(" + value + ")";
                                }
                                else
                                {
                                    value = " ($w) " + value;
                                }
                            }
                        }

                        result.append(value);
                    }

                }
                result.append(")");
            }

            context.setCurrentType( ctorValue != null ? ctorValue.getClass() : clazz );
            context.setCurrentAccessor( clazz );
            context.setCurrentObject( ctorValue );

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

        context.remove( "_ctorClass" );

        return result.toString();
    }

    public String toSetSourceString( OgnlContext context, Object target )
    {
        return "";
    }

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