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.UnsupportedCompilationException;

import java.beans.IntrospectionException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * Implementation of PropertyAccessor that uses reflection on the target object's class to find a field or a pair of
 * set/get methods with the given property name.
 */
public class ObjectPropertyAccessor
    implements PropertyAccessor
{

    /**
     * Returns OgnlRuntime.NotFound if the property does not exist.
     */
    public Object getPossibleProperty( Map<String, Object> context, Object target, String name )
        throws OgnlException
    {
        Object result;
        OgnlContext ognlContext = (OgnlContext) context;

        try
        {
            result = OgnlRuntime.getMethodValue( ognlContext, target, name, true );
            if ( result == OgnlRuntime.NotFound )
            {
                result = OgnlRuntime.getFieldValue( ognlContext, target, name, true );
            }
        }
        catch ( IntrospectionException ex )
        {
            throw new OgnlException( name, ex );
        }
        catch ( OgnlException ex )
        {
            throw ex;
        }
        catch ( Exception ex )
        {
            throw new OgnlException( name, ex );
        }

        return result;
    }

    /**
     * Returns OgnlRuntime.NotFound if the property does not exist.
     */
    public Object setPossibleProperty( Map<String, Object> context, Object target, String name, Object value )
        throws OgnlException
    {
        Object result = null;
        OgnlContext ognlContext = (OgnlContext) context;

        try
        {
            if ( !OgnlRuntime.setMethodValue( ognlContext, target, name, value, true ) )
            {
                result = OgnlRuntime.setFieldValue( ognlContext, target, name, value ) ? null : OgnlRuntime.NotFound;
            }

            if ( result == OgnlRuntime.NotFound )
            {
                Method m = OgnlRuntime.getWriteMethod( target.getClass(), name );
                if ( m != null )
                {
                    result = m.invoke( target, value );
                }
            }
        }
        catch ( IntrospectionException ex )
        {
            throw new OgnlException( name, ex );
        }
        catch ( OgnlException ex )
        {
            throw ex;
        }
        catch ( Exception ex )
        {
            throw new OgnlException( name, ex );
        }

        return result;
    }

    public boolean hasGetProperty( OgnlContext context, Object target, Object oname )
        throws OgnlException
    {
        try
        {
            return OgnlRuntime.hasGetProperty( context, target, oname );
        }
        catch ( IntrospectionException ex )
        {
            throw new OgnlException( "checking if " + target + " has gettable property " + oname, ex );
        }
    }

    public boolean hasGetProperty( Map<String, Object> context, Object target, Object oname )
        throws OgnlException
    {
        return hasGetProperty( (OgnlContext) context, target, oname );
    }

    public boolean hasSetProperty( OgnlContext context, Object target, Object oname )
        throws OgnlException
    {
        try
        {
            return OgnlRuntime.hasSetProperty( context, target, oname );
        }
        catch ( IntrospectionException ex )
        {
            throw new OgnlException( "checking if " + target + " has settable property " + oname, ex );
        }
    }

    public boolean hasSetProperty( Map<String, Object> context, Object target, Object oname )
        throws OgnlException
    {
        return hasSetProperty( (OgnlContext) context, target, oname );
    }

    public Object getProperty( Map<String, Object> context, Object target, Object oname )
        throws OgnlException
    {
        String name = oname.toString();

        Object result = getPossibleProperty( context, target, name );

        if ( result == OgnlRuntime.NotFound )
        {
            throw new NoSuchPropertyException( target, name );
        }

        return result;
    }

    public void setProperty( Map<String, Object> context, Object target, Object oname, Object value )
        throws OgnlException
    {
        String name = oname.toString();

        Object result = setPossibleProperty( context, target, name, value );

        if ( result == OgnlRuntime.NotFound )
        {
            throw new NoSuchPropertyException( target, name );
        }
    }

    public Class<?> getPropertyClass( OgnlContext context, Object target, Object index )
    {
        try
        {
            Method m = OgnlRuntime.getReadMethod( target.getClass(), index.toString() );

            if ( m == null )
            {

                if ( String.class.isAssignableFrom( index.getClass() ) && !target.getClass().isArray() )
                {
                    String key = ( (String) index ).replace( "\"", "" );
                    try
                    {
                        Field f = target.getClass().getField( key );
                        if ( f != null )
                        {

                            return f.getType();
                        }
                    }
                    catch ( NoSuchFieldException e )
                    {
                        return null;
                    }
                }

                return null;
            }

            return m.getReturnType();

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

    public String getSourceAccessor( OgnlContext context, Object target, Object index )
    {
        try
        {

            String methodName = index.toString().replace( "\"", "" );
            Method m = OgnlRuntime.getReadMethod( target.getClass(), methodName );

            // try last ditch effort of checking if they were trying to do reflection via a return method value

            if ( m == null && context.getCurrentObject() != null )
            {
                m =
                    OgnlRuntime.getReadMethod( target.getClass(),
                                               context.getCurrentObject().toString().replace( "\"", "" ) );
            }
            // System.out.println("tried to get read method from target: " + target.getClass() + " with methodName:" +
            // methodName + " result: " + m);
            // try to get field if no method could be found

            if ( m == null )
            {
                try
                {
                    if ( String.class.isAssignableFrom( index.getClass() ) && !target.getClass().isArray() )
                    {
                        Field f = target.getClass().getField( methodName );

                        if ( f != null )
                        {
                            context.setCurrentType( f.getType() );
                            context.setCurrentAccessor( f.getDeclaringClass() );

                            return "." + f.getName();
                        }
                    }
                }
                catch ( NoSuchFieldException e )
                {
                    // ignore
                }

                return "";
            }

            context.setCurrentType( m.getReturnType() );
            final OgnlExpressionCompiler compiler = OgnlRuntime.getCompiler( context );
            context.setCurrentAccessor( compiler.getSuperOrInterfaceClass( m, m.getDeclaringClass() ) );

            return "." + m.getName() + "()";

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

    public String getSourceSetter( OgnlContext context, Object target, Object index )
    {
        try
        {

            String methodName = index.toString().replace( "\"", "" );
            Method m = OgnlRuntime.getWriteMethod( target.getClass(), methodName );

            if ( m == null && context.getCurrentObject() != null && context.getCurrentObject().toString() != null )
            {
                m =
                    OgnlRuntime.getWriteMethod( target.getClass(),
                                                context.getCurrentObject().toString().replace( "\"", "" ) );
            }

            if ( m == null || m.getParameterTypes() == null || m.getParameterTypes().length <= 0 )
            {
                throw new UnsupportedCompilationException( "Unable to determine setting expression on "
                    + context.getCurrentObject() + " with index of " + index );
            }

            Class<?> parm = m.getParameterTypes()[0];
            String conversion;

            if ( m.getParameterTypes().length > 1 )
            {
                throw new UnsupportedCompilationException(
                    "Object property accessors can only support single parameter setters." );
            }

            final OgnlExpressionCompiler compiler = OgnlRuntime.getCompiler( context );
            if ( parm.isPrimitive() )
            {
                Class<?> wrapClass = OgnlRuntime.getPrimitiveWrapperClass( parm );
                conversion = compiler.createLocalReference( context, "((" + wrapClass.getName()
                    + ")org.apache.commons.ognl.OgnlOps#convertValue($3," + wrapClass.getName() + ".class, true))."
                    + OgnlRuntime.getNumericValueGetter( wrapClass ), parm );

            }
            else if ( parm.isArray() )
            {
                conversion = compiler.createLocalReference( context, "(" + ExpressionCompiler.getCastString( parm )
                    + ")org.apache.commons.ognl.OgnlOps#toArray($3," + parm.getComponentType().getName() + ".class)",
                                                            parm );

            }
            else
            {
                conversion = compiler.createLocalReference( context, "(" + parm.getName()
                    + ")org.apache.commons.ognl.OgnlOps#convertValue($3," + parm.getName() + ".class)", parm );
            }

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

            return "." + m.getName() + "(" + conversion + ")";

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