package com.crm.rely.backend.util;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * @program: crm-backend
 * @description:
 * @author: houn
 * @create: 2019-08-01 11:14
 */
public class CompareUtil {
    public static List<Difference> compareValue(Object objA) {
        List<Difference> differAttr = new ArrayList<>();
        try {
            Class<?> clazzA = objA.getClass();
            Method[] methods = clazzA.getMethods();
            Object result;
            for (Method method : methods) {
                Difference difference = new Difference();
                if (method.getName().startsWith("get")) {
                    result = method.invoke(objA, null);
                    if (result == null) {
                        continue;
                    }
                    if (result instanceof List) {
                        List<Object> childList = (List) result;
                        for (Object object : childList) {
                            difference.setChildrenDifference(compareValue(object));
                        }
                    } else {
                        String nameTrim = method.getName().substring(3);
                        nameTrim = nameTrim.substring(0, 1).toLowerCase() + nameTrim.substring(1);
                        difference.setAttr(nameTrim);
                        difference.setAfter(result.toString());
                    }
                    differAttr.add(difference);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return differAttr;
    }

    public static List<Difference> compareValue(Object objA, Object objB) {
        List<Difference> differenceAttr = new ArrayList<>();
        //值都为空，则返回
        if (objA == null && objB == null) {
            return null;
        }
        //objA不为空，objB为空,则把返回objA所有字段
        if (objA != null && objB == null) {
            return compareValue(objA);
        }

        try {
            Class<?> clazzA = objA.getClass();
            Class<?> clazzB = objB.getClass();
            Method[] methods = clazzA.getMethods();
            Object resultA = null;
            Object resultB = null;
            Method methodB = null;
            for (Method method : methods) {
                if (method.getName().startsWith("get")) {
                    methodB = clazzB.getMethod(method.getName(), null);
                    resultB = methodB.invoke(objB, null);
                    resultA = method.invoke(objA, null);
                    if (resultA == null && resultB == null) {
                        continue;
                    }
                    Difference difference = new Difference();
                    String nameTrim = method.getName().substring(3);
                    nameTrim = nameTrim.substring(0, 1).toLowerCase() + nameTrim.substring(1);
                    boolean isDifference = false;
                    if (resultA == null && resultB != null) {
                        difference.setAttr(nameTrim);
                        difference.setBefore(resultB);
                        isDifference = true;
                    } else if (resultA != null && resultB == null) {
                        difference.setAttr(nameTrim);
                        difference.setAfter(resultA);
                        isDifference = true;
                    } else {
                        if (!(resultA instanceof List)) {
                            if (!resultA.equals(resultB)) {
                                difference.setAttr(nameTrim);
                                difference.setAfter(resultA);
                                difference.setBefore(resultB);
                                isDifference = true;
                            }
                        } else {
                            List<Object> listA = (List<Object>) resultA;
                            List<Object> listB = (List<Object>) resultB;

                            for (int i = 0; i < listA.size(); i++) {
                                List<Difference> childAttr;
                                if (i >= listB.size()) {
                                    childAttr = compareValue(listA.get(i), null);
                                } else {
                                    childAttr = compareValue(listA.get(i), listB.get(i));
                                }
                                difference.setChildrenDifference(childAttr);
                                isDifference = true;
                            }
                        }
                    }
                    if (isDifference) {

                        differenceAttr.add(difference);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (differenceAttr == null || differenceAttr.size() <= 0) {
            return null;
        }
        return differenceAttr;
    }
}
