/*
 *  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
 *  
 *    https://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. 
 *  
 */
package org.apache.directory.api.util;


import org.apache.directory.api.i18n.I18n;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;
import java.util.Arrays;


/**
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public final class MethodUtils
{
    /** The logger. */
    private static final Logger LOG = LoggerFactory.getLogger( MethodUtils.class );


    /**
     * Private constructor.
     */
    private MethodUtils()
    {
    }


    /**
     * A replacement for {@link java.lang.Class#getMethod} with extended capability.
     * 
     * <p>
     * This method returns parameter-list assignment-compatible method as well as
     * exact-signature matching method.
     * 
     * @param clazz The class which will be queried for the method.
     * @param candidateMethodName Name of the method been looked for.
     * @param candidateParameterTypes Types of the parameters in the signature of the method being loooked for.
     * @return The Method found.
     * @throws NoSuchMethodException when the method cannot be found
     */
    public static Method getAssignmentCompatibleMethod( Class<?> clazz,
        String candidateMethodName,
        Class<?>[] candidateParameterTypes
        ) throws NoSuchMethodException
    {
        if ( LOG.isDebugEnabled() )
        {
            StringBuilder buf = new StringBuilder();
            buf.append( "call to getAssignmentCompatibleMethod(): \n\tclazz = " );
            buf.append( clazz.getName() );
            buf.append( "\n\tcandidateMethodName = " );
            buf.append( candidateMethodName );
            buf.append( "\n\tcandidateParameterTypes = " );

            for ( Class<?> argClass : candidateParameterTypes )
            {
                buf.append( "\n\t\t" );
                buf.append( argClass.getName() );
            }

            if ( LOG.isDebugEnabled() )
            {
                LOG.debug( buf.toString() );
            }
        }

        try
        {
            // Look for exactly the same signature.
            Method exactMethod = clazz.getMethod( candidateMethodName, candidateParameterTypes );

            if ( exactMethod != null )
            {
                return exactMethod;
            }
        }
        catch ( Exception e )
        {
            if ( LOG.isInfoEnabled() )
            {
                LOG.info( I18n.msg( I18n.MSG_17009_NO_EXACT_MATCH, candidateMethodName, e ) );
            }
        }

        /**
         * Look for the assignment-compatible signature.
         */

        // Get all methods of the class.
        Method[] methods = clazz.getMethods();

        // For each method of the class...
        for ( int mx = 0; mx < methods.length; mx++ )
        {
            // If the method name does not match...
            if ( !candidateMethodName.equals( methods[mx].getName() ) )
            {
                // ... Go on with the next method.
                continue;
            }

            // ... Get parameter types list.
            Class<?>[] parameterTypes = methods[mx].getParameterTypes();

            // If parameter types list length mismatch...
            if ( parameterTypes.length != candidateParameterTypes.length )
            {
                // ... Go on with the next method.
                continue;
            }
            // If parameter types list length is OK...
            // ... For each parameter of the method...
            for ( int px = 0; px < parameterTypes.length; px++ )
            {
                // ... If the parameter is not assignment-compatible with the candidate parameter type...
                if ( !parameterTypes[px].isAssignableFrom( candidateParameterTypes[px] ) )
                {
                    // ... Go on with the next method.
                    break;
                }
            }

            // Return the only one possible and found method.
            return methods[mx];
        }

        throw new NoSuchMethodException( clazz.getName() + "." + candidateMethodName
            + "(" + Arrays.toString( candidateParameterTypes ) + ")" );
    }
}
