package com.yutou.nas.utils;

import com.yutou.nas.interfaces.ObjectInterface;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.stereotype.Controller;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestMapping;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.yutou.nas.utils.RedisTools.processOut;

public class AppTools {
    public static String getToDayNowTimeToString() {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
    }

    public static void exec(String exec, ObjectInterface objectInterface, boolean isOutQQBot, boolean isInput) {
        try {
            Process process;
            if (AppTools.isRuntimeSystemOfWindow()) {
                process = Runtime.getRuntime().exec(new String[]{
                                "cmd",
                                "/c",
                                exec
                        }
                );
            } else {
                process = Runtime.getRuntime().exec(new String[]{
                                "sh",
                                "-c",
                                exec
                        }
                );
            }
            if (isInput) {
                processOut(process.getInputStream(), objectInterface, isOutQQBot);
                processOut(process.getErrorStream());
            } else {
                processOut(process.getErrorStream(), objectInterface, isOutQQBot);
                processOut(process.getInputStream());
            }
            process.destroy();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static boolean isRuntimeSystemOfWindow() {
        return System.getProperty("os.name").contains("Windows");
    }

    public static List<Class> scanClass(String classPath, Class<? extends Annotation> annotation) {
        List<Class> classList = new ArrayList<>();
        if (ObjectUtils.isEmpty(classPath)) {
            return classList;
        }
        ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
        TypeFilter includeFilter = (metadataReader, metadataReaderFactory) -> true;
        provider.addIncludeFilter(includeFilter);
        Set<BeanDefinition> beanDefinitionSet = new HashSet<>();
        // 指定扫描的包名
        Set<BeanDefinition> candidateComponents = provider.findCandidateComponents(classPath);
        beanDefinitionSet.addAll(candidateComponents);

        beanDefinitionSet.forEach(beanDefinition -> {
            try {
                Class clazz = Class.forName(beanDefinition.getBeanClassName());

                if (!ObjectUtils.isEmpty(annotation)) {
                    if (!ObjectUtils.isEmpty(AnnotationUtils.getAnnotation(clazz, annotation))) {
                        classList.add(clazz);
                    }
                } else {
                    classList.add(clazz);
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
//            System.out.println(definition.getBeanClassName());
        });
        return classList;
    }

    public static List<String> getUrls(String packageName, String className) {
        List<Class> list = AppTools.scanClass(packageName, Controller.class);
        List<String> urls = new ArrayList<>();
        for (Class aClass : list) {
            if (className != null && !aClass.getSimpleName().equals(className)) {
                continue;
            }
            Method[] methods = aClass.getDeclaredMethods();
            for (Method method : methods) {
                RequestMapping ls = method.getAnnotation(RequestMapping.class);
                if (ls != null) {
                    urls.add(ls.value()[0]);
                }
            }
        }
        return urls;
    }
}
