package com.takensoft.common.excel.util;

import lombok.NoArgsConstructor;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.*;

@NoArgsConstructor
public final class SuperClassReflectionUtil {
    public static List<Field> getAllFields(Class<?> clazz) {
        List<Field> fields = new ArrayList<>();
        for (Class<?> clazzInclasses : getAllClassesIncludingSuperClasses(clazz, true)) {
            fields.addAll(Arrays.asList(clazzInclasses.getDeclaredFields()));
        }
        return fields;
    }

    public static Annotation getAnnotation(Class<?> clazz, Class<? extends Annotation> targetAnnotation) {
        for (Class<?> clazzInclasses : getAllClassesIncludingSuperClasses(clazz, false)) {
            if (clazzInclasses.isAnnotationPresent(targetAnnotation)) {
                return clazzInclasses.getAnnotation(targetAnnotation);
            }
        }
        return null;
    }

    public static Field getField(Class<?> clazz, String name) throws NoSuchFieldException {
        for (Class<?> clazzInclasses : getAllClassesIncludingSuperClasses(clazz, false)) {
            for (Field field : clazzInclasses.getDeclaredFields()) {
                if (field.getName().equals(name)) {
                    return clazzInclasses.getDeclaredField(name);
                }
            }
        }
        throw new NoSuchFieldException();
    }

    private static List<Class<?>> getAllClassesIncludingSuperClasses(Class<?> clazz, boolean fromSuper) {
        List<Class<?>> classes = new ArrayList<>();
        while (clazz != null) {
            classes.add(clazz);
            clazz = clazz.getSuperclass();
        }
        if (fromSuper) {
            Collections.reverse(classes);
        }
        return classes;
    }
}