/*
 * 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.
 */
package org.apache.felix.scr.impl.inject.methods;


import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

import org.apache.felix.scr.impl.inject.ActivatorParameter;
import org.apache.felix.scr.impl.inject.LifecycleMethod;
import org.apache.felix.scr.impl.inject.MethodResult;
import org.apache.felix.scr.impl.inject.ScrComponentContext;
import org.apache.felix.scr.impl.inject.internal.Annotations;
import org.apache.felix.scr.impl.inject.internal.ClassUtils;
import org.apache.felix.scr.impl.logger.ComponentLogger;
import org.apache.felix.scr.impl.metadata.DSVersion;
import org.osgi.service.log.LogService;


public class ActivateMethod extends BaseMethod<ActivatorParameter, Object> implements LifecycleMethod
{

    protected final boolean m_supportsInterfaces;

    public ActivateMethod( final String methodName,
            final boolean methodRequired,
            final Class<?> componentClass,
            final DSVersion dsVersion,
            final boolean configurableServiceProperties,
            final boolean supportsInterfaces)
    {
        super( methodName, methodRequired, componentClass, dsVersion, configurableServiceProperties );
        m_supportsInterfaces = supportsInterfaces;
    }


    @Override
    protected MethodInfo<Object> doFindMethod( final Class<?> targetClass,
            final boolean acceptPrivate,
            final boolean acceptPackage,
            final ComponentLogger logger )
        throws SuitableMethodNotAccessibleException, InvocationTargetException
    {

        boolean suitableMethodNotAccessible = false;

        try
        {
            // find the declared method in this class
            final Method method = getMethod( targetClass, getMethodName(), new Class[]
                { ClassUtils.COMPONENT_CONTEXT_CLASS }, acceptPrivate, acceptPackage, logger );
            if ( method != null )
            {
                return new MethodInfo<>(method);
            }
        }
        catch ( SuitableMethodNotAccessibleException thrown )
        {
            logger.log( LogService.LOG_DEBUG, "SuitableMethodNotAccessible", thrown );
            suitableMethodNotAccessible = true;
        }
        if (getDSVersion().isDS11())
        {
            List<Method> methods = getSortedMethods( targetClass);
            for (Method m: methods)
            {
                final Class<?>[] parameterTypes = m.getParameterTypes();
                if (parameterTypes.length == 1)
                {
                    Class<?> type = parameterTypes[0];
                    //single parameter method with parameter ComponentContext will already have been found.
                    if (type == ClassUtils.BUNDLE_CONTEXT_CLASS)
                    {
                        if ( accept( m, acceptPrivate, acceptPackage, returnValue() ) )
                        {
                            return new MethodInfo<>(m);
                        }
                        suitableMethodNotAccessible = true;
                    }
                    if (getDSVersion().isDS13() && isAnnotation(type))
                    {
                        if ( accept( m, acceptPrivate, acceptPackage, returnValue() ) )
                        {
                            return new MethodInfo<>(m);
                        }
                        suitableMethodNotAccessible = true;
                    }
                    if (type == ClassUtils.MAP_CLASS)
                    {
                        if ( accept( m, acceptPrivate, acceptPackage, returnValue() ) )
                        {
                            return new MethodInfo<>(m);
                        }
                        suitableMethodNotAccessible = true;
                    }
                    if (type == int.class)
                    {
                        if ( accept( m, acceptPrivate, acceptPackage, returnValue() ) )
                        {
                            return new MethodInfo<>(m);
                        }
                        suitableMethodNotAccessible = true;
                    }
                    if (type == Integer.class)
                    {
                        if ( accept( m, acceptPrivate, acceptPackage, returnValue() ) )
                        {
                            return new MethodInfo<>(m);
                        }
                        suitableMethodNotAccessible = true;
                    }

                }
                else if (parameterTypes.length > 1)
                {
                    boolean accept = true;
                    for (Class<?> type: parameterTypes)
                    {
                        accept = type == ClassUtils.COMPONENT_CONTEXT_CLASS
                            || type == ClassUtils.BUNDLE_CONTEXT_CLASS
                            || type == ClassUtils.MAP_CLASS
                            || ( isDeactivate() && ( type == int.class || type == Integer.class))
                            || ( getDSVersion().isDS13() && isAnnotation(type));
                        if ( !accept )
                        {
                            break;
                        }

                    }
                    if (accept)
                    {
                        if ( accept( m, acceptPrivate, acceptPackage, returnValue() ) )
                        {
                            return new MethodInfo<>(m);
                        }
                        suitableMethodNotAccessible = true;
                    }

                }
                else //no parameters
                {
                    if ( accept( m, acceptPrivate, acceptPackage, returnValue() ) )
                    {
                        return new MethodInfo<>(m);
                    }
                    suitableMethodNotAccessible = true;
                }

            }
        }

        if ( suitableMethodNotAccessible )
        {
            throw new SuitableMethodNotAccessibleException();
        }

        return null;
    }

    @Override
    protected void setTypes(Object types)
    {
        // Don't care about types
    }

    boolean isDeactivate()
    {
        return false;
    }


    /**
     * returns the declared methods of the target class, with the correct name, sorted by number of parameters ( no parameters last)
     * @param targetClass class to examine methods of
     * @return sorted methods of correct name;
     */
    List<Method> getSortedMethods(Class<?> targetClass)
    {
        List<Method> result = new ArrayList<>();
        Method[] methods = targetClass.getDeclaredMethods();
        for (Method m: methods)
        {
            if (m.getName().equals(getMethodName()))
            {
                result.add(m);
            }
        }
        Collections.sort(result, new Comparator<Method>(){

            @Override
            public int compare(Method m1, Method m2)
            {
                final int l1 = m1.getParameterTypes().length;
                final int l2 = m2.getParameterTypes().length;
                if ( l1 == 0)
                {
                    return l2;
                }
                if ( l2 == 0)
                {
                    return -l1;
                }
                if (l1 == 1 && l2 == 1)
                {
                    final Class<?> t1 = m1.getParameterTypes()[0];
                    final Class<?> t2 = m2.getParameterTypes()[0];
                    //t1, t2 can't be equal
                    if (t1 == ClassUtils.COMPONENT_CONTEXT_CLASS) return -1;
                    if (t2 == ClassUtils.COMPONENT_CONTEXT_CLASS) return 1;
                    if (t1 == ClassUtils.BUNDLE_CONTEXT_CLASS) return -1;
                    if (t2 == ClassUtils.BUNDLE_CONTEXT_CLASS) return 1;
                    if (isAnnotation(t1)) return isAnnotation(t2)? 0: -1;
                    if (isAnnotation(t2)) return 1;
                    if (t1 == ClassUtils.MAP_CLASS) return -1;
                    if (t2 == ClassUtils.MAP_CLASS) return 1;
                    if (t1 == int.class) return -1;
                    if (t2 == int.class) return 1;
                    if (t1 == Integer.class) return -1;
                    if (t2 == Integer.class) return 1;
                    return 0;
                }
                return l1 - l2;
            }

        });
        return result;
    }

    private boolean isAnnotation(final Class<?> t1)
    {
        return t1.isAnnotation() || (m_supportsInterfaces && t1.isInterface() && !(t1 == ClassUtils.MAP_CLASS));
    }


    @Override
    protected Object[] getParameters( Method method, ActivatorParameter rawParameter )
    {
        final Class<?>[] parameterTypes = method.getParameterTypes();
        final ActivatorParameter ap = rawParameter;
        final Object[] param = new Object[parameterTypes.length];
        for ( int i = 0; i < param.length; i++ )
        {
            if ( parameterTypes[i] == ClassUtils.COMPONENT_CONTEXT_CLASS )
            {
                param[i] = ap.getComponentContext();
            }
            else if ( parameterTypes[i] == ClassUtils.BUNDLE_CONTEXT_CLASS )
            {
                param[i] = ap.getComponentContext().getBundleContext();
            }
            else if ( parameterTypes[i] == ClassUtils.MAP_CLASS )
            {
                // note: getProperties() returns a ReadOnlyDictionary which is a Map
                param[i] = ap.getComponentContext().getProperties();
            }
            else if ( parameterTypes[i] == ClassUtils.INTEGER_CLASS || parameterTypes[i] == Integer.TYPE )
            {
                param[i] = ap.getReason();
            }
            else
            {
                param[i] = Annotations.toObject(parameterTypes[i],
                    (Map<String, Object>) ap.getComponentContext().getProperties(),
                    ap.getComponentContext().getBundleContext().getBundle(), m_supportsInterfaces);
            }
        }

        return param;
    }


    @Override
    protected String getMethodNamePrefix()
    {
        return "activate";
    }

    /**
     * @see org.apache.felix.scr.impl.inject.LifecycleMethod#invoke(Object,
     *      ScrComponentContext, int, MethodResult)
     */
    @Override
    public MethodResult invoke(final Object componentInstance,
            final ScrComponentContext componentContext,
    		final int reason,
    		final MethodResult methodCallFailureResult) {
        return invoke(componentInstance, new ActivatorParameter(componentContext, reason), methodCallFailureResult);
    }

    @Override
    public MethodResult invoke(final  Object componentInstance,
    		final ActivatorParameter rawParameter,
    		final MethodResult methodCallFailureResult)
    {
        if (methodExists( rawParameter.getComponentContext().getLogger() ))
        {
            return super.invoke(componentInstance, rawParameter, methodCallFailureResult );
        }
        return null;
    }

}
