package com.kiselev.reflection.ui.annotation;

import com.kiselev.reflection.ui.indent.IndentUtils;
import sun.reflect.annotation.AnnotationType;

import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AnnotationsUtils {

    public String getAnnotations(AnnotatedElement annotatedElement) {
        String annotations = "";

        String indent = new IndentUtils().getIndent(annotatedElement);

        for (Annotation annotation : annotatedElement.getAnnotations()) {
            annotations += indent + getAnnotation(annotation) + "\n";
        }

        return annotations;
    }

    private String getAnnotation(Annotation annotation) {
        String annotationSignature = "";

        String annotationSign = "@";

        String annotationName = annotation.annotationType().getSimpleName();

        String annotationArguments = getAnnotationArguments(annotation);

        annotationSignature += annotationSign + annotationName + annotationArguments;

        return annotationSignature;
    }

    private String getAnnotationArguments(Annotation annotation) {
        String annotationArguments = "";

        List<String> arguments = new ArrayList<>();

        for (Map.Entry<String, Object> entry : getAnnotationMemberTypes(annotation).entrySet()) {
            arguments.add(entry.getKey() + " = " + entry.getValue());
        }

        if (!arguments.isEmpty()) {
            annotationArguments += "(" + String.join(", ", arguments) + ")";
        }

        return annotationArguments;
    }

    private Map<String, Object> getAnnotationMemberTypes(Annotation annotation) {
        Map<String, Object> map = new HashMap<String, Object>();

        try {
            Class<? extends Annotation> annotationTypeClass = annotation.annotationType();
            Method[] methods = annotationTypeClass.getDeclaredMethods();

            for (Method method : methods) {
                method.setAccessible(true);
                map.put(method.getName(), method.invoke(annotation));
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }

        return map;
    }
}

@@ -100,26 +100,26 @@
 s;%0D%0A
+%0D%0A
 import 
-sun.reflect
+java.lang
 .ann
@@ -140,17 +140,11 @@
 tion
-Type
 ;%0D%0A
-%0D%0A
 impo
@@ -156,37 +156,73 @@
 va.lang.
-annotation.Annotation
+reflect.AnnotatedElement;%0D%0Aimport java.lang.reflect.Array
 ;%0D%0Aimpor
@@ -245,9 +245,14 @@
 ect.
-*
+Method
 ;%0D%0Ai
@@ -2146,24 +2146,26 @@
 ble(true);%0D%0A
+%0D%0A
             
@@ -2172,192 +2172,1406 @@
     
-map.put(method.getName(), method.invoke(annotation));%0D%0A            %7D%0D%0A        %7D catch (Exception exception) %7B%0D%0A            exception.printStackTrace();%0D%0A        %7D%0D%0A%0D%0A        return map
+Object value = method.invoke(annotation);%0D%0A                String fullValue = value.toString();%0D%0A%0D%0A                if (value.getClass().isArray()) %7B%0D%0A                    List%3CString%3E listValue = new ArrayList%3CString%3E();%0D%0A                    for (Object arrayValue : getArrayValues(value)) %7B%0D%0A                        if (arrayValue.getClass().isEnum()) %7B%0D%0A                            listValue.add(getEnumValue(arrayValue));%0D%0A                        %7D else %7B%0D%0A                            listValue.add(arrayValue.toString());%0D%0A                        %7D%0D%0A                    %7D%0D%0A%0D%0A                    fullValue = %22%5B%22 + String.join(%22, %22, listValue) + %22%5D%22;%0D%0A                %7D%0D%0A%0D%0A                if (value.getClass().isEnum()) %7B%0D%0A                    fullValue = getEnumValue(value);%0D%0A                %7D%0D%0A%0D%0A                map.put(method.getName(), fullValue);%0D%0A            %7D%0D%0A        %7D catch (Exception exception) %7B%0D%0A            exception.printStackTrace();%0D%0A        %7D%0D%0A%0D%0A        return map;%0D%0A    %7D%0D%0A%0D%0A    private String getEnumValue(Object object) %7B%0D%0A        return object.getClass().getSimpleName() + %22.%22 + object;%0D%0A    %7D%0D%0A%0D%0A    private Object%5B%5D getArrayValues(Object object) %7B%0D%0A        int length = Array.getLength(object);%0D%0A        Object%5B%5D objects = new Object%5Blength%5D;%0D%0A%0D%0A        for (int i = 0; i %3C length; i++) %7B%0D%0A            objects%5Bi%5D = (Array.get(object, i));%0D%0A        %7D%0D%0A        return objects
 ;%0D%0A 

Fix value in annotations