/*
 * 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.deltaspike.core.util;

import javax.enterprise.inject.Typed;
import javax.enterprise.inject.spi.Annotated;
import javax.enterprise.inject.spi.AnnotatedCallable;
import javax.enterprise.inject.spi.AnnotatedConstructor;
import javax.enterprise.inject.spi.AnnotatedField;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.AnnotatedParameter;
import javax.enterprise.inject.spi.AnnotatedType;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * <p>
 * Utilities for working with {@link Annotated}s.
 * </p>
 * <p/>
 * <p>
 * Includes utilities to check the equality of and create unique id's for
 * <code>Annotated</code> instances.
 * </p>
 */
public final class Annotateds
{
    private static final char SEPARATOR = ';';

    private Annotateds()
    {
        // this is a utility class with statics only
    }

    /**
     * Does the first stage of comparing AnnoatedCallables, however it cannot
     * compare the method parameters
     */
    @Typed()
    private static class AnnotatedCallableComparator<T>
        implements Comparator<AnnotatedCallable<? super T>>, Serializable
    {

        public int compare(AnnotatedCallable<? super T> arg0, AnnotatedCallable<? super T> arg1)
        {
            // compare the names first
            int result = (arg0.getJavaMember().getName().compareTo(arg1.getJavaMember().getName()));
            if (result != 0)
            {
                return result;
            }
            result = arg0.getJavaMember().getDeclaringClass().getName().compareTo(arg1.getJavaMember()
                    .getDeclaringClass().getName());
            if (result != 0)
            {
                return result;
            }
            result = arg0.getParameters().size() - arg1.getParameters().size();
            return result;
        }

    }

    @Typed()
    private static class AnnotatedMethodComparator<T>
        implements Comparator<AnnotatedMethod<? super T>>, Serializable
    {

        private AnnotatedCallableComparator<T> callableComparator = new AnnotatedCallableComparator<T>();

        public static <T> Comparator<AnnotatedMethod<? super T>> instance()
        {
            return new AnnotatedMethodComparator<T>();
        }

        public int compare(AnnotatedMethod<? super T> arg0, AnnotatedMethod<? super T> arg1)
        {
            int result = callableComparator.compare(arg0, arg1);
            if (result != 0)
            {
                return result;
            }
            for (int i = 0; i < arg0.getJavaMember().getParameterTypes().length; ++i)
            {
                Class<?> p0 = arg0.getJavaMember().getParameterTypes()[i];
                Class<?> p1 = arg1.getJavaMember().getParameterTypes()[i];
                result = p0.getName().compareTo(p1.getName());
                if (result != 0)
                {
                    return result;
                }
            }
            return 0;
        }

    }

    @Typed()
    private static class AnnotatedConstructorComparator<T>
        implements Comparator<AnnotatedConstructor<? super T>>, Serializable
    {

        private AnnotatedCallableComparator<T> callableComparator = new AnnotatedCallableComparator<T>();

        public static <T> Comparator<AnnotatedConstructor<? super T>> instance()
        {
            return new AnnotatedConstructorComparator<T>();
        }

        public int compare(AnnotatedConstructor<? super T> arg0, AnnotatedConstructor<? super T> arg1)
        {
            int result = callableComparator.compare(arg0, arg1);
            if (result != 0)
            {
                return result;
            }
            for (int i = 0; i < arg0.getJavaMember().getParameterTypes().length; ++i)
            {
                Class<?> p0 = arg0.getJavaMember().getParameterTypes()[i];
                Class<?> p1 = arg1.getJavaMember().getParameterTypes()[i];
                result = p0.getName().compareTo(p1.getName());
                if (result != 0)
                {
                    return result;
                }
            }
            return 0;
        }

    }

    @Typed()
    private static class AnnotatedFieldComparator<T>
        implements Comparator<AnnotatedField<? super T>>, Serializable
    {

        public static <T> Comparator<AnnotatedField<? super T>> instance()
        {
            return new AnnotatedFieldComparator<T>();
        }

        public int compare(AnnotatedField<? super T> arg0, AnnotatedField<? super T> arg1)
        {
            if (arg0.getJavaMember().getName().equals(arg1.getJavaMember().getName()))
            {
                return arg0.getJavaMember().getDeclaringClass().getName().compareTo(arg1.getJavaMember()
                        .getDeclaringClass().getName());
            }
            return arg0.getJavaMember().getName().compareTo(arg1.getJavaMember().getName());
        }

    }

    @Typed()
    private static class AnnotationComparator implements Comparator<Annotation>, Serializable
    {

        public static final Comparator<Annotation> INSTANCE = new AnnotationComparator();

        public int compare(Annotation arg0, Annotation arg1)
        {
            return arg0.annotationType().getName().compareTo(arg1.annotationType().getName());
        }
    }

    @Typed()
    private static class MethodComparator implements Comparator<Method>
    {

        public static final Comparator<Method> INSTANCE = new MethodComparator();

        public int compare(Method arg0, Method arg1)
        {
            return arg0.getName().compareTo(arg1.getName());
        }
    }

    /**
     * Generates a deterministic signature for an {@link AnnotatedType}. Two
     * <code>AnnotatedType</code>s that have the same annotations and underlying
     * type will generate the same signature.
     * <p/>
     * This can be used to create a unique bean id for a passivation capable bean
     * that is added directly through the SPI.
     *
     * @param annotatedType The type to generate a signature for
     * @return A string representation of the annotated type
     */
    public static <X> String createTypeId(AnnotatedType<X> annotatedType)
    {
        return createTypeId(annotatedType.getJavaClass(), annotatedType.getAnnotations(), annotatedType.getMethods(),
                annotatedType.getFields(), annotatedType.getConstructors());
    }

    /**
     * Generates a unique signature for a concrete class. Annotations are not
     * read directly from the class, but are read from the
     * <code>annotations</code>, <code>methods</code>, <code>fields</code> and
     * <code>constructors</code> arguments
     *
     * @param clazz        The java class type
     * @param annotations  Annotations present on the java class
     * @param methods      The AnnotatedMethods to include in the signature
     * @param fields       The AnnotatedFields to include in the signature
     * @param constructors The AnnotatedConstructors to include in the signature
     * @return A string representation of the type
     */
    public static <X> String createTypeId(Class<X> clazz, Collection<Annotation> annotations,
                                          Collection<AnnotatedMethod<? super X>> methods,
                                          Collection<AnnotatedField<? super X>> fields,
                                          Collection<AnnotatedConstructor<X>> constructors)
    {
        StringBuilder builder = new StringBuilder();

        builder.append(clazz.getName());
        builder.append(createAnnotationCollectionId(annotations));
        builder.append("{");

        // now deal with the fields
        List<AnnotatedField<? super X>> sortedFields = new ArrayList<AnnotatedField<? super X>>();
        sortedFields.addAll(fields);
        Collections.sort(sortedFields, AnnotatedFieldComparator.<X>instance());
        for (AnnotatedField<? super X> field : sortedFields)
        {
            if (!field.getAnnotations().isEmpty())
            {
                builder.append(createFieldId(field));
                builder.append(SEPARATOR);
            }
        }

        // methods
        List<AnnotatedMethod<? super X>> sortedMethods = new ArrayList<AnnotatedMethod<? super X>>();
        sortedMethods.addAll(methods);
        Collections.sort(sortedMethods, AnnotatedMethodComparator.<X>instance());
        for (AnnotatedMethod<? super X> method : sortedMethods)
        {
            if (!method.getAnnotations().isEmpty() || hasMethodParameters(method))
            {
                builder.append(createCallableId(method));
                builder.append(SEPARATOR);
            }
        }

        // constructors
        List<AnnotatedConstructor<? super X>> sortedConstructors = new ArrayList<AnnotatedConstructor<? super X>>();
        sortedConstructors.addAll(constructors);
        Collections.sort(sortedConstructors, AnnotatedConstructorComparator.<X>instance());
        for (AnnotatedConstructor<? super X> constructor : sortedConstructors)
        {
            if (!constructor.getAnnotations().isEmpty() || hasMethodParameters(constructor))
            {
                builder.append(createCallableId(constructor));
                builder.append(SEPARATOR);
            }
        }
        builder.append("}");

        return builder.toString();
    }

    /**
     * Generates a deterministic signature for an {@link AnnotatedField}. Two
     * <code>AnnotatedField</code>s that have the same annotations and
     * underlying field will generate the same signature.
     */
    public static <X> String createFieldId(AnnotatedField<X> field)
    {
        return createFieldId(field.getJavaMember(), field.getAnnotations());
    }

    /**
     * Creates a deterministic signature for a {@link Field}.
     *
     * @param field       The field to generate the signature for
     * @param annotations The annotations to include in the signature
     */
    public static <X> String createFieldId(Field field, Collection<Annotation> annotations)
    {
        StringBuilder builder = new StringBuilder();
        builder.append(field.getDeclaringClass().getName());
        builder.append('.');
        builder.append(field.getName());
        builder.append(createAnnotationCollectionId(annotations));
        return builder.toString();
    }

    /**
     * Generates a deterministic signature for an {@link AnnotatedCallable}. Two
     * <code>AnnotatedCallable</code>s that have the same annotations and
     * underlying callable will generate the same signature.
     */
    public static <X> String createCallableId(AnnotatedCallable<X> method)
    {
        StringBuilder builder = new StringBuilder();
        builder.append(method.getJavaMember().getDeclaringClass().getName());
        builder.append('.');
        builder.append(method.getJavaMember().getName());
        builder.append(createAnnotationCollectionId(method.getAnnotations()));
        builder.append(createParameterListId(method.getParameters()));
        return builder.toString();
    }

    /**
     * Creates a deterministic signature for a {@link Method}.
     *
     * @param method      The method to generate the signature for
     * @param annotations The annotations to include in the signature
     * @param parameters  The {@link AnnotatedParameter}s to include in the
     *                    signature
     */
    public static <X> String createMethodId(Method method, Set<Annotation> annotations,
                                            List<AnnotatedParameter<X>> parameters)
    {
        StringBuilder builder = new StringBuilder();
        builder.append(method.getDeclaringClass().getName());
        builder.append('.');
        builder.append(method.getName());
        builder.append(createAnnotationCollectionId(annotations));
        builder.append(createParameterListId(parameters));
        return builder.toString();
    }

    /**
     * Creates a deterministic signature for a {@link Constructor}.
     *
     * @param constructor The constructor to generate the signature for
     * @param annotations The annotations to include in the signature
     * @param parameters  The {@link AnnotatedParameter}s to include in the
     *                    signature
     */
    public static <X> String createConstructorId(Constructor<X> constructor, Set<Annotation> annotations,
                                                 List<AnnotatedParameter<X>> parameters)
    {
        StringBuilder builder = new StringBuilder();
        builder.append(constructor.getDeclaringClass().getName());
        builder.append('.');
        builder.append(constructor.getName());
        builder.append(createAnnotationCollectionId(annotations));
        builder.append(createParameterListId(parameters));
        return builder.toString();
    }

    /**
     * Generates a unique string representation of a list of
     * {@link AnnotatedParameter}s.
     */
    public static <X> String createParameterListId(List<AnnotatedParameter<X>> parameters)
    {
        StringBuilder builder = new StringBuilder();
        builder.append("(");
        for (int i = 0; i < parameters.size(); ++i)
        {
            AnnotatedParameter<X> ap = parameters.get(i);
            builder.append(createParameterId(ap));
            if (i + 1 != parameters.size())
            {
                builder.append(',');
            }
        }
        builder.append(")");
        return builder.toString();
    }

    /**
     * Creates a string representation of an {@link AnnotatedParameter}.
     */
    public static <X> String createParameterId(AnnotatedParameter<X> annotatedParameter)
    {
        return createParameterId(annotatedParameter.getBaseType(), annotatedParameter.getAnnotations());
    }

    /**
     * Creates a string representation of a given type and set of annotations.
     */
    public static <X> String createParameterId(Type type, Set<Annotation> annotations)
    {
        StringBuilder builder = new StringBuilder();
        if (type instanceof Class<?>)
        {
            Class<?> c = (Class<?>) type;
            builder.append(c.getName());
        }
        else
        {
            builder.append(type.toString());
        }
        builder.append(createAnnotationCollectionId(annotations));
        return builder.toString();
    }

    /**
     * <p>
     * Compares {@link AnnotatedField}s for equality.
     * </p>
     * <p>
     * Two {@link AnnotatedField}s are considered equal if they have the same
     * underlying field and annotations.
     * </p>
     */
    public static boolean compareAnnotatedField(AnnotatedField<?> f1, AnnotatedField<?> f2)
    {
        if (!f1.getJavaMember().equals(f2.getJavaMember()))
        {
            return false;
        }
        return compareAnnotated(f1, f2);
    }

    /**
     * <p>
     * Compare {@link AnnotatedCallable}s for equality.
     * </p>
     * <p/>
     * <p>
     * Two {@link AnnotatedCallable}s are considered equal if they have the same
     * underlying callable and annotations.
     * </p>
     */
    public static boolean compareAnnotatedCallable(AnnotatedCallable<?> m1, AnnotatedCallable<?> m2)
    {
        if (!m1.getJavaMember().equals(m2.getJavaMember()))
        {
            return false;
        }
        if (!compareAnnotated(m1, m2))
        {
            return false;
        }
        return compareAnnotatedParameters(m1.getParameters(), m2.getParameters());
    }

    /**
     * <p>
     * Compares two {@link AnnotatedType}s for equality.
     * </p>
     * <p/>
     * <p>
     * Two {@link AnnotatedType}s are considered equal if they have the same
     * underlying type and annotations, and all members have the same
     * annotations.
     * </p>
     */
    public static boolean compareAnnotatedTypes(AnnotatedType<?> t1, AnnotatedType<?> t2)
    {
        if (!t1.getJavaClass().equals(t2.getJavaClass()))
        {
            return false;
        }
        if (!compareAnnotated(t1, t2))
        {
            return false;
        }

        if (t1.getFields().size() != t2.getFields().size())
        {
            return false;
        }
        Map<Field, AnnotatedField<?>> fields = new HashMap<Field, AnnotatedField<?>>();
        for (AnnotatedField<?> f : t2.getFields())
        {
            fields.put(f.getJavaMember(), f);
        }
        for (AnnotatedField<?> f : t1.getFields())
        {
            if (fields.containsKey(f.getJavaMember()))
            {
                if (!compareAnnotatedField(f, fields.get(f.getJavaMember())))
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }

        if (t1.getMethods().size() != t2.getMethods().size())
        {
            return false;
        }
        Map<Method, AnnotatedMethod<?>> methods = new HashMap<Method, AnnotatedMethod<?>>();
        for (AnnotatedMethod<?> f : t2.getMethods())
        {
            methods.put(f.getJavaMember(), f);
        }
        for (AnnotatedMethod<?> f : t1.getMethods())
        {
            if (methods.containsKey(f.getJavaMember()))
            {
                if (!compareAnnotatedCallable(f, methods.get(f.getJavaMember())))
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }
        if (t1.getConstructors().size() != t2.getConstructors().size())
        {
            return false;
        }
        Map<Constructor<?>, AnnotatedConstructor<?>> constructors =
                new HashMap<Constructor<?>, AnnotatedConstructor<?>>();
        for (AnnotatedConstructor<?> f : t2.getConstructors())
        {
            constructors.put(f.getJavaMember(), f);
        }
        for (AnnotatedConstructor<?> f : t1.getConstructors())
        {
            if (constructors.containsKey(f.getJavaMember()))
            {
                if (!compareAnnotatedCallable(f, constructors.get(f.getJavaMember())))
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }
        return true;

    }

    private static <X> boolean hasMethodParameters(AnnotatedCallable<X> callable)
    {
        for (AnnotatedParameter<X> parameter : callable.getParameters())
        {
            if (!parameter.getAnnotations().isEmpty())
            {
                return true;
            }
        }
        return false;
    }

    private static String createAnnotationCollectionId(Collection<Annotation> annotations)
    {
        if (annotations.isEmpty())
        {
            return "";
        }

        StringBuilder builder = new StringBuilder();
        builder.append('[');

        List<Annotation> annotationList = new ArrayList<Annotation>(annotations.size());
        annotationList.addAll(annotations);
        Collections.sort(annotationList, AnnotationComparator.INSTANCE);

        for (Annotation a : annotationList)
        {
            builder.append('@');
            builder.append(a.annotationType().getName());
            builder.append('(');
            Method[] declaredMethods = a.annotationType().getDeclaredMethods();
            List<Method> methods = new ArrayList<Method>(declaredMethods.length);
            methods.addAll(Arrays.asList(declaredMethods));
            Collections.sort(methods, MethodComparator.INSTANCE);

            for (int i = 0; i < methods.size(); ++i)
            {
                Method method = methods.get(i);
                try
                {
                    Object value = method.invoke(a);
                    builder.append(method.getName());
                    builder.append('=');
                    if (value.getClass().isArray())
                    {
                        Class<?> componentType = value.getClass().getComponentType();
                        if (componentType.isAnnotation())
                        {
                            builder.append(Arrays.asList((Object[]) value));
                        }
                        else if (componentType instanceof Class<?>)
                        {
                            builder.append(createArrayId(value));
                        }
                        else
                        {
                            builder.append(value.toString());
                        }
                    }
                    else
                    {
                        builder.append(value.toString());
                    }
                }
                catch (NullPointerException e)
                {
                    throw new RuntimeException("NullPointerException accessing annotation member, annotation:"
                            + a.annotationType().getName() + " member: " + method.getName(), e);
                }
                catch (IllegalArgumentException e)
                {
                    throw new RuntimeException("IllegalArgumentException accessing annotation member, annotation:"
                            + a.annotationType().getName() + " member: " + method.getName(), e);
                }
                catch (IllegalAccessException e)
                {
                    throw new RuntimeException("IllegalAccessException accessing annotation member, annotation:"
                            + a.annotationType().getName() + " member: " + method.getName(), e);
                }
                catch (InvocationTargetException e)
                {
                    throw new RuntimeException("InvocationTargetException accessing annotation member, annotation:"
                            + a.annotationType().getName() + " member: " + method.getName(), e);
                }
                if (i + 1 != methods.size())
                {
                    builder.append(',');
                }
            }
            builder.append(')');
        }
        builder.append(']');
        return builder.toString();
    }

    /**
     * Appends comma separated list of class names from classArray to builder
     */
    private static String createArrayId(Object value)
    {
        if (value instanceof int[])
        {
            return Arrays.toString((int[]) value);
        }
        if (value instanceof short[])
        {
            return Arrays.toString((short[]) value);
        }
        if (value instanceof byte[])
        {
            return Arrays.toString((byte[]) value);
        }
        if (value instanceof char[])
        {
            return Arrays.toString((char[]) value);
        }
        if (value instanceof long[])
        {
            return Arrays.toString((long[]) value);
        }
        if (value instanceof float[])
        {
            return Arrays.toString((float[]) value);
        }
        if (value instanceof double[])
        {
            return Arrays.toString((double[]) value);
        }
        if (value instanceof String[])
        {
            return Arrays.toString((String[]) value);
        }

        return createClassArrayId((Class<?>[]) value);
    }

    /**
     * Appends comma separated list of class names from classArray to builder
     */
    private static String createClassArrayId(Class<?>[] classArray)
    {
        StringBuilder builder = new StringBuilder();
        builder.append('[');
        for (int i = 0; i < classArray.length; i++)
        {
            builder.append(classArray[i].getName());
            if (i + 1 != classArray.length)
            {
                builder.append(',');
            }
        }
        builder.append(']');
        return builder.toString();
    }

    /**
     * Compares two annotated elements to see if they have the same annotations
     */
    private static boolean compareAnnotated(Annotated a1, Annotated a2)
    {
        return a1.getAnnotations().equals(a2.getAnnotations());
    }

    /**
     * Compares two annotated elements to see if they have the same annotations
     */
    private static boolean compareAnnotatedParameters(List<? extends AnnotatedParameter<?>> p1,
                                                      List<? extends AnnotatedParameter<?>> p2)
    {
        if (p1.size() != p2.size())
        {
            return false;
        }
        for (int i = 0; i < p1.size(); ++i)
        {
            if (!compareAnnotated(p1.get(i), p2.get(i)))
            {
                return false;
            }
        }
        return true;
    }

}
