package org.apache.maven.shared.utils.introspection;

/*
 * 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 java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;

import org.apache.maven.shared.utils.StringUtils;
import org.apache.maven.shared.utils.introspection.MethodMap.AmbiguousException;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;


/**
 * <p>Using simple dotted expressions to extract the values from an Object instance,
 * For example we might want to extract a value like: <code>project.build.sourceDirectory</code></p>
 * <p/>
 * <p>The implementation supports indexed, nested and mapped properties similar to the JSP way.</p>
 *
 * @author <a href="mailto:jason@maven.org">Jason van Zyl </a>
 * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
 * @see <a href="http://struts.apache.org/1.x/struts-taglib/indexedprops.html">
 * http://struts.apache.org/1.x/struts-taglib/indexedprops.html</a>
 */
public class ReflectionValueExtractor
{
    private static final Class<?>[] CLASS_ARGS = new Class[0];

    private static final Object[] OBJECT_ARGS = new Object[0];

    /**
     * Use a WeakHashMap here, so the keys (Class objects) can be garbage collected.
     * This approach prevents permgen space overflows due to retention of discarded
     * classloaders.
     */
    private static final Map<Class<?>, ClassMap> CLASS_MAPS = new WeakHashMap<Class<?>, ClassMap>();

    static final int EOF = -1;

    static final char PROPERTY_START = '.';

    static final char INDEXED_START = '[';

    static final char INDEXED_END = ']';

    static final char MAPPED_START = '(';

    static final char MAPPED_END = ')';

    static class Tokenizer
    {
        final String expression;

        int idx;

        Tokenizer( String expression )
        {
            this.expression = expression;
        }

        public int peekChar()
        {
            return idx < expression.length() ? expression.charAt( idx ) : EOF;
        }

        public int skipChar()
        {
            return idx < expression.length() ? expression.charAt( idx++ ) : EOF;
        }

        public String nextToken( char delimiter )
        {
            int start = idx;

            while ( idx < expression.length() && delimiter != expression.charAt( idx ) )
            {
                idx++;
            }

            // delimiter MUST be present
            if ( idx <= start || idx >= expression.length() )
            {
                return null;
            }

            return expression.substring( start, idx++ );
        }

        public String nextPropertyName()
        {
            final int start = idx;

            while ( idx < expression.length() && Character.isJavaIdentifierPart( expression.charAt( idx ) ) )
            {
                idx++;
            }

            // property name does not require delimiter
            if ( idx <= start || idx > expression.length() )
            {
                return null;
            }

            return expression.substring( start, idx );
        }

        public int getPosition()
        {
            return idx < expression.length() ? idx : EOF;
        }

        // to make tokenizer look pretty in debugger
        @Override
        public String toString()
        {
            return idx < expression.length() ? expression.substring( idx ) : "<EOF>";
        }
    }

    private ReflectionValueExtractor()
    {
    }

    /**
     * <p>The implementation supports indexed, nested and mapped properties.</p>
     * <p/>
     * <ul>
     * <li>nested properties should be defined by a dot, i.e. "user.address.street"</li>
     * <li>indexed properties (java.util.List or array instance) should be contains <code>(\\w+)\\[(\\d+)\\]</code>
     * pattern, i.e. "user.addresses[1].street"</li>
     * <li>mapped properties should be contains <code>(\\w+)\\((.+)\\)</code> pattern,
     *  i.e. "user.addresses(myAddress).street"</li>
     * <ul>
     *
     * @param expression not null expression
     * @param root       not null object
     * @return the object defined by the expression
     * @throws IntrospectionException if any
     */
    public static Object evaluate( @Nonnull String expression, @Nullable Object root )
        throws IntrospectionException
    {
        return evaluate( expression, root, true );
    }

    /**
     * <p>
     * The implementation supports indexed, nested and mapped properties.
     * </p>
     * <p/>
     * <ul>
     * <li>nested properties should be defined by a dot, i.e. "user.address.street"</li>
     * <li>indexed properties (java.util.List or array instance) should be contains <code>(\\w+)\\[(\\d+)\\]</code>
     * pattern, i.e. "user.addresses[1].street"</li>
     * <li>mapped properties should be contains <code>(\\w+)\\((.+)\\)</code> pattern, i.e.
     * "user.addresses(myAddress).street"</li>
     * <ul>
     *
     * @param expression not null expression
     * @param root not null object
     * @param trimRootToken trim root token yes/no.
     * @return the object defined by the expression
     * @throws IntrospectionException if any
     */
    public static Object evaluate( @Nonnull String expression, @Nullable Object root, boolean trimRootToken )
        throws IntrospectionException
    {
        Object value = root;

        // ----------------------------------------------------------------------
        // Walk the dots and retrieve the ultimate value desired from the
        // MavenProject instance.
        // ----------------------------------------------------------------------

        if ( StringUtils.isEmpty( expression ) || !Character.isJavaIdentifierStart( expression.charAt( 0 ) ) )
        {
            return null;
        }

        boolean hasDots = expression.indexOf( PROPERTY_START ) >= 0;

        final Tokenizer tokenizer;
        if ( trimRootToken && hasDots )
        {
            tokenizer = new Tokenizer( expression );
            tokenizer.nextPropertyName();
            if ( tokenizer.getPosition() == EOF )
            {
                return null;
            }
        }
        else
        {
            tokenizer = new Tokenizer( "." + expression );
        }

        int propertyPosition = tokenizer.getPosition();
        while ( value != null && tokenizer.peekChar() != EOF )
        {
            switch ( tokenizer.skipChar() )
            {
                case INDEXED_START:
                    value =
                        getIndexedValue( expression, propertyPosition, tokenizer.getPosition(), value,
                                         tokenizer.nextToken( INDEXED_END ) );
                    break;
                case MAPPED_START:
                    value =
                        getMappedValue( expression, propertyPosition, tokenizer.getPosition(), value,
                                        tokenizer.nextToken( MAPPED_END ) );
                    break;
                case PROPERTY_START:
                    propertyPosition = tokenizer.getPosition();
                    value = getPropertyValue( value, tokenizer.nextPropertyName() );
                    break;
                default:
                    // could not parse expression
                    return null;
            }
        }

        return value;
    }

    private static Object getMappedValue( final String expression, final int from, final int to, final Object value,
                                          final String key )
        throws IntrospectionException
    {
        if ( value == null || key == null )
        {
            return null;
        }

        if ( value instanceof Map )
        {
            Object[] localParams = new Object[] { key };
            ClassMap classMap = getClassMap( value.getClass() );
            try
            {
                Method method = classMap.findMethod( "get", localParams );
                return method.invoke( value, localParams );
            }
            catch ( AmbiguousException e )
            {
                throw new IntrospectionException( e );
            }
            catch ( IllegalAccessException e )
            {
                throw new IntrospectionException( e );
            }
            catch ( InvocationTargetException e )
            {
                throw new IntrospectionException( e.getTargetException() );
            }

        }

        final String message =
            String.format( "The token '%s' at position '%d' refers to a java.util.Map, but the value "
                + "seems is an instance of '%s'", expression.subSequence( from, to ), from, value.getClass() );

        throw new IntrospectionException( message );
    }

    private static Object getIndexedValue( final String expression, final int from, final int to, final Object value,
                                           final String indexStr )
        throws IntrospectionException
    {
        try
        {
            int index = Integer.parseInt( indexStr );

            if ( value.getClass().isArray() )
            {
                return Array.get( value, index );
            }

            if ( value instanceof List )
            {
                ClassMap classMap = getClassMap( value.getClass() );
                // use get method on List interface
                Object[] localParams = new Object[] { index };
                Method method = null;
                try
                {
                    method = classMap.findMethod( "get", localParams );
                    return method.invoke( value, localParams );
                }
                catch ( AmbiguousException e )
                {
                    throw new IntrospectionException( e );
                }
                catch ( IllegalAccessException e )
                {
                    throw new IntrospectionException( e );
                }
            }
        }
        catch ( NumberFormatException e )
        {
            return null;
        }
        catch ( InvocationTargetException e )
        {
            // catch array index issues gracefully, otherwise release
            if ( e.getCause() instanceof IndexOutOfBoundsException )
            {
                return null;
            }

            throw new IntrospectionException( e.getTargetException() );
        }

        final String message =
            String.format( "The token '%s' at position '%d' refers to a java.util.List or an array, but the value "
                + "seems is an instance of '%s'", expression.subSequence( from, to ), from, value.getClass() );

        throw new IntrospectionException( message );
    }

    private static Object getPropertyValue( Object value, String property )
        throws IntrospectionException
    {
        if ( value == null || property == null )
        {
            return null;
        }

        ClassMap classMap = getClassMap( value.getClass() );
        String methodBase = StringUtils.capitalizeFirstLetter( property );
        String methodName = "get" + methodBase;
        try
        {
            Method method = classMap.findMethod( methodName, CLASS_ARGS );

            if ( method == null )
            {
                // perhaps this is a boolean property??
                methodName = "is" + methodBase;

                method = classMap.findMethod( methodName, CLASS_ARGS );
            }

            if ( method == null )
            {
                return null;
            }

            return method.invoke( value, OBJECT_ARGS );
        }
        catch ( InvocationTargetException e )
        {
            throw new IntrospectionException( e.getTargetException() );
        }
        catch ( AmbiguousException e )
        {
            throw new IntrospectionException( e );
        }
        catch ( IllegalAccessException e )
        {
            throw new IntrospectionException( e );
        }
    }

    private static ClassMap getClassMap( Class<?> clazz )
    {
        ClassMap classMap = CLASS_MAPS.get( clazz );

        if ( classMap == null )
        {
            classMap = new ClassMap( clazz );

            CLASS_MAPS.put( clazz, classMap );
        }

        return classMap;
    }
}
