// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package io.v.v23.vom;

import io.v.v23.vdl.VdlArray;
import io.v.v23.vdl.VdlComplex128;
import io.v.v23.vdl.VdlComplex64;
import io.v.v23.vdl.VdlEnum;
import io.v.v23.vdl.VdlList;
import io.v.v23.vdl.VdlMap;
import io.v.v23.vdl.VdlSet;
import io.v.v23.vdl.VdlStruct;
import io.v.v23.vdl.VdlType;
import io.v.v23.vdl.VdlValue;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * ReflectUtil provides helpers to get object properties and create class instances from reflection.
 */
final class ReflectUtil {
    /**
     * Creates an instance of java primitives, one of boolean, byte, short, int, long, float,
     * double, String. Handles java types and VDL types.
     *
     * @param target the target containing java class and VDL type information
     * @param value the value of primitive to be created
     * @return an instance of VDL primitive containing the provided value if the target class
     *         is inherited from {@code VdlValue}; returns provided value otherwise
     * @throws ConversionException if the instance of the target class can't be created
     */
    static Object createPrimitive(ConversionTarget target, Object value, Class<?> valueType)
            throws ConversionException {
        Class<?> targetClass = target.getTargetClass();
        try {
            if (targetClass.getSuperclass() == VdlValue.class) {
                return targetClass.getConstructor(VdlType.class, valueType)
                        .newInstance(target.getVdlType(), value);
            } else if (VdlValue.class.isAssignableFrom(targetClass)) {
                return targetClass.getConstructor(valueType).newInstance(value);
            } else {
                return value;
            }
        } catch (Exception e) {
            throw new ConversionException(value, targetClass, e);
        }
    }

    /**
     * Creates an instance of VDL complex. The target class should be inherited from
     * {@code VdlValue}.
     */
    static VdlValue createComplex(ConversionTarget target, double real, double imag)
            throws ConversionException {
        Class<?> targetClass = target.getTargetClass();
        try {
            if (targetClass == VdlComplex64.class) {
                return new VdlComplex64(target.getVdlType(), (float) real, (float) imag);
            } else if (targetClass == VdlComplex128.class) {
                return new VdlComplex128(target.getVdlType(), real, imag);
            } else if (VdlComplex64.class.isAssignableFrom(targetClass)) {
                return (VdlValue) targetClass.getConstructor(Float.TYPE, Float.TYPE)
                        .newInstance((float) real, (float) imag);
            } else if (VdlComplex128.class.isAssignableFrom(targetClass)) {
                return (VdlValue) targetClass.getConstructor(Double.TYPE, Double.TYPE)
                        .newInstance(real, imag);
            }
        } catch (Exception e) {
            throw new ConversionException(
                    new VdlComplex128(real, imag), targetClass, e);
        }
        throw new ConversionException(new VdlComplex128(real, imag), targetClass);
    }

    /**
     * Creates an instance of VDL enum. The target class should be inherited from {@code VdlEnum}.
     */
    static VdlEnum createEnum(ConversionTarget target, String label) throws ConversionException {
        Class<?> targetClass = target.getTargetClass();
        if (targetClass == VdlEnum.class) {
            return new VdlEnum(target.getVdlType(), label);
        }
        try {
            return (VdlEnum) targetClass.getMethod("valueOf", String.class)
                    .invoke(null, label);
        } catch (Exception e) {
            throw new ConversionException(label, targetClass, e);
        }
    }

    private static Object createNamedGeneric(Class<?> targetClass, Object impl)
            throws ConversionException {
        try {
            if (VdlArray.class.isAssignableFrom(targetClass)) {
                return construct(targetClass, impl.getClass(), impl);
            } else if (VdlList.class.isAssignableFrom(targetClass)) {
                return construct(targetClass, List.class, impl);
            } else if (VdlMap.class.isAssignableFrom(targetClass)) {
                return construct(targetClass, Map.class, impl);
            } else if (VdlSet.class.isAssignableFrom(targetClass)) {
                return construct(targetClass, Set.class, impl);
            }
        } catch (Exception e) {
            throw new ConversionException(impl, targetClass, e);
        }
        throw new ConversionException(impl, targetClass);
     }

    private static Object construct(
            Class<?> targetClass, Class<?> ctorParamType, Object... ctorArgs)
            throws NoSuchMethodException, IllegalAccessException, InvocationTargetException,
                   InstantiationException {
        Constructor<?> ctor = targetClass.getConstructor(ctorParamType);
        ctor.setAccessible(true);
        return ctor.newInstance(ctorArgs);
    }

    /**
     * Creates an instance of generic type, one of array, list, map, set.
     *
     * @param target the target containing java class and VDL type information
     * @param impl the implementation of generic type to be created
     * @return an instance of VDL generic containing wrapped around the provided implementation
     *         object if the target class is inherited from {@code VdlValue}; returns provided
     *         implementation object otherwise
     * @throws ConversionException if the instance of the target class can't be created
     */
    @SuppressWarnings("unchecked")
    static Object createGeneric(ConversionTarget target, Object impl) throws ConversionException {
        Class<?> targetClass = target.getTargetClass();
        if (targetClass == VdlArray.class) {
            return new VdlArray<Object>(target.getVdlType(), (Object[]) impl);
        } else if (targetClass == VdlList.class) {
            return new VdlList<Object>(target.getVdlType(), (List<Object>) impl);
        } else if (targetClass == VdlSet.class) {
            return new VdlSet<Object>(target.getVdlType(), (Set<Object>) impl);
        } else if (targetClass == VdlMap.class) {
            return new VdlMap<Object, Object>(target.getVdlType(), (Map<Object, Object>) impl);
        } else if (VdlValue.class.isAssignableFrom(targetClass)) {
            return createNamedGeneric(targetClass, impl);
        } else {
            return impl;
        }
    }

    /**
     * Creates an instance of VDL struct. The target class should be inherited from
     * {@code AbstractVdlStruct}.
     */
    static Object createStruct(ConversionTarget target) throws ConversionException {
        Class<?> targetClass = target.getTargetClass();
        if (targetClass == VdlStruct.class) {
            return new VdlStruct(target.getVdlType());
        }
        try {
            Constructor<?> ctor = targetClass.getConstructor();
            ctor.setAccessible(true);
            return ctor.newInstance();
        } catch (Exception e) {
            throw new ConversionException(target.getVdlType(), targetClass, e);
        }
    }

    /**
     * Returns a {@code Class} object that is represented by provided {@code Type} object.
     */
    static Class<?> getRawClass(Type type) {
        if (type instanceof Class) {
            return (Class<?>) type;
        } else if (type instanceof ParameterizedType) {
            return getRawClass(((ParameterizedType) type).getRawType());
        } else if (type instanceof GenericArrayType) {
            Class<?> component = getRawClass(((GenericArrayType) type).getGenericComponentType());
            return Array.newInstance(component, 0).getClass();
        } else {
            return null;
        }
    }

    /**
     * Returns type of element at provided index for generic or array type.
     *
     * @param type the generic type
     * @throws ConversionException if the type has no element at index
     * @returns an array of element types; the returned array is empty if the provided type
     *          is not generic or array
     */
    static Type getElementType(Type type, int index) throws ConversionException {
        Type[] types = new Type[0];
        if (type instanceof Class) {
            Class<?> klass = (Class<?>) type;
            if (klass.isArray()) {
                types = new Type[]{klass.getComponentType()};
            } else {
                return getElementType(klass.getGenericSuperclass(), index);
            }
        } else if (type instanceof ParameterizedType) {
            types = ((ParameterizedType) type).getActualTypeArguments();
        } else if (type instanceof GenericArrayType) {
            types = new Type[]{((GenericArrayType) type).getGenericComponentType()};
        }
        if (index < 0 || index >= types.length) {
            throw new ConversionException("Type " + type + " has no element at index " + index);
        }
        return types[index];
    }

    /**
     * Sets the value of the indexed element of the specified array object to the specified value.
     *
     * @param array the array
     * @param index the index into the array
     * @param value new value of the indexed element
     * @param elementClass the class of elements in the array
     */
    static void setArrayValue(Object array, int index, Object value, Class<?> elementClass) {
        if (elementClass == Boolean.TYPE) {
            Array.setBoolean(array, index, (Boolean) value);
        } else if (elementClass == Byte.TYPE) {
            Array.setByte(array, index, (Byte) value);
        } else if (elementClass == Double.TYPE) {
            Array.setDouble(array, index, (Double) value);
        } else if (elementClass == Float.TYPE) {
            Array.setFloat(array, index, (Float) value);
        } else if (elementClass == Integer.TYPE) {
            Array.setInt(array, index, (Integer) value);
        } else if (elementClass == Long.TYPE) {
            Array.setLong(array, index, (Long) value);
        } else if (elementClass == Short.TYPE) {
            Array.setShort(array, index, (Short) value);
        } else {
            Array.set(array, index, value);
        }
    }
}
