package com.brilliance.mda.runtime.mda.driver.compile;

import com.brilliance.mda.support.td.ModuleInfoManager;
import org.apache.commons.io.Charsets;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import java.io.FileNotFoundException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class EmitterManager {

    private final static Logger log = LoggerFactory.getLogger(ModuleInfoManager.class);

    private static final ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();

    private static final Map<String, Map<String, String>> initIgnoreMap = new HashMap<>();

    private static final Map<String, Map<String, String>> defaultIgnoreMap = new HashMap<>();

    private static final Map<String, Map<String, String>> ruleIgnoreMap = new HashMap<>();

    private static final Map<String, Map<String, String>> checkIgnoreMap = new HashMap<>();

    public static void loadEmitterIgnoreInfo(Class<?> aClass) {
        try {
            String moduleName = aClass.getSimpleName();
            String filename = aClass.getSimpleName() + ".txt";
            Resource[] resources = resourceResolver.getResources("classpath:ignoreRule/" + filename);
            // File file = resources[0].getFile();
            InputStream stream2 = resources[0].getInputStream();
            log.info("加载ignoreRule：{}", filename);
            List<String> lines = IOUtils.readLines(stream2, Charsets.toCharset(StandardCharsets.UTF_8));
            for (String line : lines) {
                String[] fields = line.split("\t");
//                log.info("加载ignoreRule-line:{},fields.length：{}", line, fields.length);
                if (fields.length < 2)
                    continue;

                String target = fields[0].trim();
                String field1 = fields[1].trim();
                String methodExpress = field1;
                methodExpress = methodExpress.substring(methodExpress.indexOf("(") + 1);
                methodExpress = methodExpress.substring(0, methodExpress.lastIndexOf(")")).trim();
                String[] methodExpresses = methodExpress.split(",");
                if (methodExpresses.length < 3)
                    continue;

                String order = methodExpresses[0].trim();
                String path = methodExpresses[1].trim().replaceAll("\"", "");
                String method = methodExpresses[2].substring(methodExpresses[2].lastIndexOf("::") + 2);

                String expression = String.format("%s#%s#%s#%s", target, path, method, order);
                if (field1.startsWith("execCheckItem")) {
                    log.info("加载ignoreRule.check方法：{}", expression);
                    Map<String, String> map = checkIgnoreMap.computeIfAbsent(moduleName, k -> new HashMap<>());
                    map.put(expression, line);
                } else if (field1.startsWith("execRuleItem")) {
                    Map<String, String> map = ruleIgnoreMap.computeIfAbsent(moduleName, k -> new HashMap<>());
                    map.put(expression, line);
                } else if (field1.startsWith("execDefaultItem")) {
                    Map<String, String> map = defaultIgnoreMap.computeIfAbsent(moduleName, k -> new HashMap<>());
                    map.put(expression, line);
                } else if (field1.startsWith("execInitItem")) {
                    Map<String, String> map = initIgnoreMap.computeIfAbsent(moduleName, k -> new HashMap<>());
                    map.put(expression, line);
                }
            }
        } catch (FileNotFoundException ignore) {
            log.warn("[这是提示信息，不影响运行]从resources/ignoreRule下查找文件失败。{}",ignore.getMessage());
        } catch (Exception e) {
            log.error("从resources/ignoreRule下查找文件失败", e);
            throw new IllegalArgumentException(e.getCause());
        }
    }

    public static boolean isIgnoreInitMethod(String moduleName, String methodName) {
        Map<String, String> ignoreMap = initIgnoreMap.getOrDefault(moduleName, null);
        return ignoreMap != null && ignoreMap.containsKey(methodName);
    }

    public static boolean isIgnoreCheckMethod(String moduleName, String methodName) {
        Map<String, String> ignoreMap = checkIgnoreMap.getOrDefault(moduleName, null);
        return ignoreMap != null && ignoreMap.containsKey(methodName);
    }

    public static boolean isIgnoreRuleMethod(String moduleName, String methodName) {
        Map<String, String> ignoreMap = ruleIgnoreMap.getOrDefault(moduleName, null);
        return ignoreMap != null && ignoreMap.containsKey(methodName);
    }

    public static boolean isIgnoreDefaultMethod(String moduleName, String methodName) {
        Map<String, String> ignoreMap = defaultIgnoreMap.getOrDefault(moduleName, null);
        return ignoreMap != null && ignoreMap.containsKey(methodName);
    }

    public static String getMethodNameByRule(String target, String path, String method, int order) {
        return String.format("%s#%s#%s#%s", target, path, method, order);
    }
}
