/*
 * 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.ace.test.utils;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import aQute.bnd.annotation.ProviderType;

/**
 * Utility class that injects dependencies. Can be used to unit test service implementations.
 */
@ProviderType
public class TestUtils {
    public static final String UNIT = "unit";
    public static final String INTEGRATION = "integration";
    public static final String SMOKE = "smoke";
    public static final String PERFORMANCE = "performance";
    public static final String UI = "ui";
    public static final String BROKEN = "broken";
    /**
     * Configures an object to use a null object for the specified service interface.
     *
     * @param object the object
     * @param iface the service interface
     */
    public static <T> void configureObject(Object object, Class<T> iface) {
        configureObject(object, iface, createNullObject(iface));
    }

    /**
     * Creates a null object for a service interface.
     *
     * @param iface the service interface
     * @return a null object
     */
    @SuppressWarnings("unchecked")
    public static <T> T createNullObject(Class<T> iface) {
        return (T) Proxy.newProxyInstance(iface.getClassLoader(), new Class[] { iface }, new NullObject());
    }

    /**
     * Wraps the given handler in an adapter that will try to pass on received invocations to the hander if that has
     * an applicable methods else it defaults to a NullObject.
     *
     * @param iface the service interface
     * @param handler the handler to pass invocations to.
     * @return an adapter that will try to pass on received invocations to the given handler
     */
    @SuppressWarnings("unchecked")
    public static <T> T createMockObjectAdapter(Class<T> iface, final Object handler) {
        return (T) Proxy.newProxyInstance(iface.getClassLoader(), new Class[] { iface }, new NullObject() {

            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                try {
                    Method bridge = handler.getClass().getMethod(method.getName(), method.getParameterTypes());
                    bridge.setAccessible(true);
                    return bridge.invoke(handler, args);
                }
                catch (NoSuchMethodException ex) {
                    return super.invoke(proxy, method, args);
                }
                catch (InvocationTargetException ex) {
                    throw ex.getCause();
                }
            }
        });
    }

    /**
     * Configures an object to use a specific implementation for the specified service interface.
     *
     * @param object the object
     * @param iface the service interface
     * @param instance the implementation
     */
    @SuppressWarnings("unchecked")
    public static void configureObject(Object object, Class iface, Object instance) {
        Class serviceClazz = object.getClass();

        while (serviceClazz != null) {
            Field[] fields = serviceClazz.getDeclaredFields();
            AccessibleObject.setAccessible(fields, true);
            for (int j = 0; j < fields.length; j++) {
                if (fields[j].getType().equals(iface)) {
                    try {
                        // synchronized makes sure the field is actually written to immediately
                        synchronized (new Object()) {
                            fields[j].set(object, instance);
                        }
                    }
                    catch (Exception e) {
                        throw new IllegalStateException("Could not set field " + fields[j].getName() + " on " + object);
                    }
                }
            }
            serviceClazz = serviceClazz.getSuperclass();
        }
    }

    static class NullObject implements InvocationHandler {
        private static final Boolean DEFAULT_BOOLEAN = Boolean.FALSE;

        private static final Byte DEFAULT_BYTE = new Byte((byte) 0);

        private static final Short DEFAULT_SHORT = new Short((short) 0);

        private static final Integer DEFAULT_INT = new Integer(0);

        private static final Long DEFAULT_LONG = new Long(0);

        private static final Float DEFAULT_FLOAT = new Float(0.0f);

        private static final Double DEFAULT_DOUBLE = new Double(0.0);

        /**
         * Invokes a method on this null object. The method will return a default value without doing anything.
         */
        @SuppressWarnings("unchecked")
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Class returnType = method.getReturnType();
            if (returnType.equals(Boolean.class) || returnType.equals(Boolean.TYPE)) {
                return DEFAULT_BOOLEAN;
            }
            else if (returnType.equals(Byte.class) || returnType.equals(Byte.TYPE)) {
                return DEFAULT_BYTE;
            }
            else if (returnType.equals(Short.class) || returnType.equals(Short.TYPE)) {
                return DEFAULT_SHORT;
            }
            else if (returnType.equals(Integer.class) || returnType.equals(Integer.TYPE)) {
                return DEFAULT_INT;
            }
            else if (returnType.equals(Long.class) || returnType.equals(Long.TYPE)) {
                return DEFAULT_LONG;
            }
            else if (returnType.equals(Float.class) || returnType.equals(Float.TYPE)) {
                return DEFAULT_FLOAT;
            }
            else if (returnType.equals(Double.class) || returnType.equals(Double.TYPE)) {
                return DEFAULT_DOUBLE;
            }
            else {
                return null;
            }
        }
    }
}
