package org.diagbot.graph.jdbc;

import org.diagbot.graph.annotation.FromProperty;
import org.diagbot.graph.annotation.RelationName;
import org.diagbot.graph.annotation.ToProperty;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @Auther: fyeman
 * @Date: 2018/9/26/026 15:40
 * @Description:
 */
public class Neo4jUtil {
    public Neo4jModel createModel(Object obj) throws IllegalAccessException {
        Neo4jModel model = new Neo4jModel();
        try {
            List<Field> fields = joinFields(obj);
            for (Field f : fields) {
                ToProperty p = f.getAnnotation(ToProperty.class);
                f.setAccessible(true);
                if (p != null) {
                    if (StringUtils.isEmpty(p.value())) {
                        model.getToProperties().put(f.getName(), f.get(obj));
                    } else {
                        model.getToProperties().put(p.value(), f.get(obj));
                    }
                }

                FromProperty l = f.getAnnotation(FromProperty.class);

                if (l != null) {
                    if (StringUtils.isEmpty(l.value())) {
                        model.getFromProperties().put(f.getName(), f.get(obj));
                    } else {
                        model.getFromProperties().put(l.value(), f.get(obj));
                    }
                }

                RelationName r = f.getAnnotation(RelationName.class);
                if (r != null) {
                    model.setRelationName(String.valueOf(f.get(obj)));
                }
            }
        } catch (IllegalAccessException iae) {
            throw iae;
        }
        return model;
    }

    private List<Field> joinFields(Object obj) {
        List<Field> asList = Arrays.asList(obj.getClass().getDeclaredFields());
        List<Field> fieldList = new ArrayList<>(asList);

        List<Field> resultList = new ArrayList<>(asList);

        boolean isFind = false;
        Class c = obj.getClass().getSuperclass();
        while(c != Object.class) {
            Field[] fields = obj.getClass().getSuperclass().getDeclaredFields();
            for (Field f : fields) {
                for (Field has : fieldList) {
                    if (has.getName().equals(f.getName())) {
                        isFind = true;
                    }
                }
                if (!isFind) {
                    resultList.add(f);
                }
                isFind = false;
            }
            c = c.getClass().getSuperclass();
        }
        return resultList;
    }
}
