/*
 * 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.dm.impl;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Executor;
import java.util.concurrent.FutureTask;
import java.util.function.Supplier;

import org.apache.felix.dm.DependencyManager;
import org.osgi.service.cm.ConfigurationException;

/**
 * Utility methods for invoking callbacks. Lookups of callbacks are accellerated by using a LRU cache.
 * 
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
 */
public class InvocationUtil {
	/**
	 * Constant Used to get empty constructor by reflection. 
	 */
    private static final Class<?>[] VOID = new Class[] {};
    
    private static final Map<Key, Method> m_methodCache;
    static {
        int size = 4096;
        try {
            String value = System.getProperty(DependencyManager.METHOD_CACHE_SIZE);
            if (value != null) {
                size = Integer.parseInt(value);
            }
        }
        catch (Exception e) {}
        m_methodCache = new LRUMap(Math.max(size, 64));
    }
    
    /**
     * Interface internally used to handle a ConfigurationAdmin update synchronously, in a component executor queue.
     */
    @FunctionalInterface
    public interface ConfigurationHandler {
        public void handle() throws Exception;
    }
    
    /**
     * Represents a component instance
     */
    public static final class ComponentInstance {
    	/**
    	 * The component instance
    	 */
    	public final Object m_instance;
    	
    	/**
    	 * The index of the constructor used when creating the component instance
    	 */
    	public final int m_ctorIndex;
    	
    	/**
    	 * creates a component instance
    	 * @param instance the component instance
    	 * @param ctorIndex the index of the CallbackTypeDef used when creating the component instance
    	 */
    	public ComponentInstance(Object instance, int ctorIndex) {
    		m_instance = instance;
    		m_ctorIndex = ctorIndex;
    	}
    }
    
    /**
     * Invokes a callback method on an instance. The code will search for a callback method with
     * the supplied name and any of the supplied signatures in order, invoking the first one it finds.
     * 
     * @param instance the instance to invoke the method on
     * @param methodName the name of the method
     * @param signatures the ordered list of signatures to look for
     * @param parameters the parameter values to use for each potential signature
     * @return whatever the method returns
     * @throws NoSuchMethodException when no method could be found
     * @throws IllegalArgumentException when illegal values for this methods arguments are supplied 
     * @throws IllegalAccessException when the method cannot be accessed
     * @throws InvocationTargetException when the method that was invoked throws an exception
     */
    public static Object invokeCallbackMethod(Object instance, String methodName, Class<?>[][] signatures, Object[][] parameters) throws NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        Class<?> currentClazz = instance.getClass();
        while (currentClazz != null && currentClazz != Object.class) {
            try {
                return invokeMethod(instance, currentClazz, methodName, signatures, parameters, false);
            }
            catch (NoSuchMethodException nsme) {
                // ignore
            }
            currentClazz = currentClazz.getSuperclass();
        }
        throw new NoSuchMethodException(methodName);
    }

    /**
     * Invoke a method on an instance.
     * 
     * @param object the instance to invoke the method on
     * @param clazz the class of the instance
     * @param name the name of the method
     * @param signatures the signatures to look for in order
     * @param parameters the parameter values for the signatures
     * @param isSuper <code>true</code> if this is a superclass and we should therefore not look for private methods
     * @return whatever the method returns
     * @throws NoSuchMethodException when no method could be found
     * @throws IllegalArgumentException when illegal values for this methods arguments are supplied 
     * @throws IllegalAccessException when the method cannot be accessed
     * @throws InvocationTargetException when the method that was invoked throws an exception
     */
    public static Object invokeMethod(Object object, Class<?> clazz, String name, Class<?>[][] signatures, Object[][] parameters, boolean isSuper) throws NoSuchMethodException, InvocationTargetException, IllegalArgumentException, IllegalAccessException {
        if (object == null) {
            throw new IllegalArgumentException("Instance cannot be null");
        }
        if (clazz == null) {
            throw new IllegalArgumentException("Class cannot be null");
        }
        
        // if we're talking to a proxy here, dig one level deeper to expose the
        // underlying invocation handler (we do the same for injecting instances)
        if (Proxy.isProxyClass(clazz)) {
            object = Proxy.getInvocationHandler(object);
            clazz = object.getClass();
        }
        
        Method m = null;
        for (int i = 0; i < signatures.length; i++) {
            Class<?>[] signature = signatures[i];
            m = getDeclaredMethod(clazz, name, signature, isSuper);
            if (m != null) {
                return m.invoke(object, parameters[i]);
            }
        }
        throw new NoSuchMethodException(name);
    }
    
    /**
     * Invokes a callback method on an instance. The code will search for a callback method with
     * the supplied name and any of the supplied signatures in order, invoking the first one it finds.
     * 
     * @param instance the instance to invoke the method on
     * @param methodName the name of the method
     * @param signatures the ordered list of signatures to look for
     * @param parameters the parameter values to use for each potential signature
     * @return whatever the method returns
     * @throws NoSuchMethodException when no method could be found
     * @throws IllegalArgumentException when illegal values for this methods arguments are supplied 
     * @throws IllegalAccessException when the method cannot be accessed
     * @throws InvocationTargetException when the method that was invoked throws an exception
     */
    public static Object invokeCallbackMethod(Object instance, String methodName, Class<?>[][] signatures, Supplier<?>[][] parameters) throws NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        Class<?> currentClazz = instance.getClass();
        while (currentClazz != null && currentClazz != Object.class) {
            try {
                return invokeMethod(instance, currentClazz, methodName, signatures, parameters, false);
            }
            catch (NoSuchMethodException nsme) {
                // ignore
            }
            currentClazz = currentClazz.getSuperclass();
        }
        throw new NoSuchMethodException(methodName);
    }

    /**
     * Invoke a method on an instance.
     * 
     * @param object the instance to invoke the method on
     * @param clazz the class of the instance
     * @param name the name of the method
     * @param signatures the signatures to look for in order
     * @param paramsSupplier the parameter values for the signatures
     * @param isSuper <code>true</code> if this is a superclass and we should therefore not look for private methods
     * @return whatever the method returns
     * @throws NoSuchMethodException when no method could be found
     * @throws IllegalArgumentException when illegal values for this methods arguments are supplied 
     * @throws IllegalAccessException when the method cannot be accessed
     * @throws InvocationTargetException when the method that was invoked throws an exception
     */
    public static Object invokeMethod(Object object, Class<?> clazz, String name, Class<?>[][] signatures, Supplier<?>[][] paramsSupplier, boolean isSuper) throws NoSuchMethodException, InvocationTargetException, IllegalArgumentException, IllegalAccessException {
        if (object == null) {
            throw new IllegalArgumentException("Instance cannot be null");
        }
        if (clazz == null) {
            throw new IllegalArgumentException("Class cannot be null");
        }
        
        // if we're talking to a proxy here, dig one level deeper to expose the
        // underlying invocation handler (we do the same for injecting instances)
        if (Proxy.isProxyClass(clazz)) {
            object = Proxy.getInvocationHandler(object);
            clazz = object.getClass();
        }
        
        Method m = null;
        for (int i = 0; i < signatures.length; i++) {
            Class<?>[] signature = signatures[i];
            m = getDeclaredMethod(clazz, name, signature, isSuper);
            if (m != null) {
            	Object[] params = new Object[paramsSupplier[i].length];
            	for (int j = 0; j < params.length; j ++) {
            		params[j] = paramsSupplier[i][j].get();            		
            	}
                return m.invoke(object, params);
            }
        }
        throw new NoSuchMethodException(name);
    }

    /**
     * Gets a callback method on an instance. The code will search for a callback method with
     * the supplied name and any of the supplied signatures in order, get the first one it finds.
     * 
     * @param instance the instance to invoke the method on
     * @param methodName the name of the method
     * @param signatures the ordered list of signatures to look for
     * @return the method found, or null
     */
    public static Method getCallbackMethod(Object instance, String methodName, Class<?>[][] signatures) {
        Class<?> currentClazz = instance.getClass();
        while (currentClazz != null && currentClazz != Object.class) {
        	Method m = getMethod(instance, currentClazz, methodName, signatures, false);
        	if (m != null) {
        		return m;
        	}
            currentClazz = currentClazz.getSuperclass();
        }
        return null;
    }

    /**
     * Gets a callback method on a class. The code will search for a callback method with
     * the supplied name and any of the supplied signatures in order, get the first one it finds.
     * 
     * @param instance the instance to invoke the method on
     * @param methodName the name of the method
     * @param signatures the ordered list of signatures to look for
     * @return the method found, or null
     */
    public static Method getCallbackMethod(Class<?> type, String methodName, Class<?>[][] signatures) {
        Class<?> currentClazz = type;
        while (currentClazz != null && currentClazz != Object.class) {
        	Method m = getMethod(currentClazz, methodName, signatures, false);
        	if (m != null) {
        		return m;
        	}
            currentClazz = currentClazz.getSuperclass();
        }
        return null;
    }

    /**
     * Get a method on an instance.
     * TODO: rework this class to avoid code duplication with invokeMethod !
     * 
     * @param object the instance to invoke the method on
     * @param clazz the class of the instance
     * @param name the name of the method
     * @param signatures the signatures to look for in order
     * @param isSuper <code>true</code> if this is a superclass and we should therefore not look for private methods
     * @return the found method, or null if not found
     */
    public static Method getMethod(Object object, Class<?> clazz, String name, Class<?>[][] signatures, boolean isSuper) {
        if (object == null) {
            throw new IllegalArgumentException("Instance cannot be null");
        }
        if (clazz == null) {
            throw new IllegalArgumentException("Class cannot be null");
        }
        
        // if we're talking to a proxy here, dig one level deeper to expose the
        // underlying invocation handler (we do the same for injecting instances)
        if (Proxy.isProxyClass(clazz)) {
            object = Proxy.getInvocationHandler(object);
            clazz = object.getClass();
        }
        
        return getMethod(clazz, name, signatures, isSuper);
    }
    
    /**
     * Get a method on an instance.
     * TODO: rework this class to avoid code duplication with invokeMethod !
     * 
     * @param object the instance to invoke the method on
     * @param clazz the class of the instance
     * @param name the name of the method
     * @param signatures the signatures to look for in order
     * @param isSuper <code>true</code> if this is a superclass and we should therefore not look for private methods
     * @return the found method, or null if not found
     */
    private static Method getMethod(Class<?> clazz, String name, Class<?>[][] signatures, boolean isSuper) {
        if (clazz == null) {
            throw new IllegalArgumentException("Class cannot be null");
        }
                
        Method m = null;
        for (int i = 0; i < signatures.length; i++) {
            Class<?>[] signature = signatures[i];
            m = getDeclaredMethod(clazz, name, signature, isSuper);
            if (m != null) {
            	break;
            }
        }
        return m;
    }

    public static ComponentInstance createInstance(Class<?> clazz, CallbackTypeDef ctorArgs) throws Exception {    			
    	Constructor<?>[] ctors = clazz.getConstructors(); 
    	for (int index = 0; index < ctorArgs.m_sigs.length; index ++) {
    		Class<?>[] sigs = ctorArgs.m_sigs[index];    		
    		for (Constructor<?> ctor : ctors) {    	
    			Class<?>[] ctorParamTypes = ctor.getParameterTypes(); 
    			if (Arrays.equals(sigs, ctorParamTypes)) {
    				ctor.setAccessible(true);
    				Object instance = ctor.newInstance(ctorArgs.m_args[index]);
    				return new ComponentInstance(instance, index);
    			}
    		}
    	}
    	throw new InstantiationException("No suitable constructor found for class " + clazz.getName());    	
    }
    
    /**
     * Instantiates a component. The first public constructor which contains any of the specified arguments is used.
     * @param clazz the class name used to instantiate the component
     * @param ctorArgs constructor arguments. An empty map means the first public constructor is used.
     * @return the component instance
     */
    public static Object createInstance(Class<?> clazz, Map<Class<?>, Object> ctorArgs) throws SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {    			
    	if (ctorArgs.size() == 0) {
    		Constructor<?> ctor = clazz.getConstructor(VOID);
    		ctor.setAccessible(true);
			return ctor.newInstance();
    	}
    	
    	Constructor<?>[] ctors = clazz.getConstructors(); 
    	for (Constructor<?> ctor : ctors) {
			Class<?>[] ctorParamTypes = ctor.getParameterTypes();
			boolean match = true;
			for (Class<?> ctopParamType : ctorParamTypes) {
				if (ctorArgs.get(ctopParamType) == null) {
					match = false;
					break;
				}
			}
			if (match) {
				Object[] paramValues = new Object[ctorParamTypes.length];
				int index = 0;
				for (Class<?> ctorParamType : ctorParamTypes) {
					paramValues[index ++] = ctorArgs.get(ctorParamType);
				}
				ctor.setAccessible(true);
				return ctor.newInstance(paramValues);
			}
    	}
    	throw new InstantiationException("No suitable constructor found for class " + clazz.getName());    	
    }
    
    private static Method getDeclaredMethod(Class<?> clazz, String name, Class<?>[] signature, boolean isSuper) {
        // first check our cache
        Key key = new Key(clazz, name, signature);
        Method m = null;
        synchronized (m_methodCache) {
            m = (Method) m_methodCache.get(key);
            if (m != null) {
                return m;
            }
            else if (m_methodCache.containsKey(key)) {
                // the key is in our cache, it just happens to have a null value
                return null;
            }
        }
        // then do a lookup
        try {
            m = clazz.getDeclaredMethod(name, signature);
            if (!(isSuper && Modifier.isPrivate(m.getModifiers()))) {
                m.setAccessible(true);
            }
        }
        catch (NoSuchMethodException e) {
        }
        synchronized (m_methodCache) {
            m_methodCache.put(key, m);
        }
        return m;
    }
    
    public static class Key {
        private final Class<?> m_clazz;
        private final String m_name;
        private final Class<?>[] m_signature;

        public Key(Class<?> clazz, String name, Class<?>[] signature) {
            m_clazz = clazz;
            m_name = name;
            m_signature = signature;
        }

        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((m_clazz == null) ? 0 : m_clazz.hashCode());
            result = prime * result + ((m_name == null) ? 0 : m_name.hashCode());
            result = prime * result + Arrays.hashCode(m_signature);
            return result;
        }

        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Key other = (Key) obj;
            if (m_clazz == null) {
                if (other.m_clazz != null)
                    return false;
            }
            else if (!m_clazz.equals(other.m_clazz))
                return false;
            if (m_name == null) {
                if (other.m_name != null)
                    return false;
            }
            else if (!m_name.equals(other.m_name))
                return false;
            if (!Arrays.equals(m_signature, other.m_signature))
                return false;
            return true;
        }
    }
    
    @SuppressWarnings("serial")
    public static class LRUMap extends LinkedHashMap<Key, Method> {
        private final int m_size;
        
        public LRUMap(int size) {
            m_size = size;
        }
        
        protected boolean removeEldestEntry(java.util.Map.Entry<Key, Method> eldest) {
            return size() > m_size;
        }
    }
    
    /**
     * Invokes a configuration update callback synchronously, but through the component executor queue.
     */
    public static void invokeUpdated(Executor queue, ConfigurationHandler handler) throws ConfigurationException {
        Callable<Exception> result = () -> {
            try {
                handler.handle();
            } catch (Exception e) {
                return e;
            }
            return null;
        };
        
        FutureTask<Exception> ft = new FutureTask<>(result);
        queue.execute(ft);
                
        try {
            Exception err = ft.get();
            if (err != null) {
                throw err;
            }
        }
        
        catch (ConfigurationException e) {
            throw e;
        }

        catch (Throwable error) {
            Throwable rootCause = error.getCause();
            if (rootCause != null) {
                if (rootCause instanceof ConfigurationException) {
                    throw (ConfigurationException) rootCause;
                }
                throw new ConfigurationException("", "Configuration update error, unexpected exception.", rootCause);
            } else {
                throw new ConfigurationException("", "Configuration update error, unexpected exception.", error);
            }
        }
    }

}
