package org.diagbot.common.push.cache;

import org.diagbot.common.push.bean.RelevantFeature;
import org.diagbot.common.push.bean.ResultMappingFilter;
import org.diagbot.common.push.bean.Rule;
import org.diagbot.common.push.bean.RuleApp;
import org.diagbot.nlp.participle.cfg.Configuration;
import org.diagbot.nlp.participle.cfg.DefaultConfig;
import org.diagbot.nlp.util.NlpCache;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class ApplicationCacheUtil {

    //词库同义词定义
    public static Map<String, Map<String, String>> standard_info_synonym_map = null;
    //诊断科室衍射
    public static Map<String, String> doc_result_mapping_diag_map = null;
    //特征性别 年龄过滤等
    public static Map<String, Map<String, ResultMappingFilter>> doc_result_mapping_filter_map = null;
    //化验辅检体征 性别 年龄过滤等
    public static Map<String, Map<String, ResultMappingFilter>> doc_result_mapping_lpvSex_filter_map = null;
    // 规则
    public static Map<String, List<Rule>> kl_rule_filter_map = null;
    //危险值提醒
    public static Map<String, RuleApp> kl_rule_app_filter_map = null;
    //pacs关系抽取过滤
    public static Map<String, Map<String, String>> kl_diagnose_detail_filter_map = null;
    //朴素贝叶斯
    public static Map<String, Map<String, Float>> doc_feature_naivebayes_prob_map = null;
    //朴素贝叶斯规则过滤
    public static Map<String, Map<String, Float>> relevant_feature_bayes_map = null;
    //体征过滤对比表信息
    public static Map<String, RelevantFeature> relevant_feature_map = null;

    public static Map<String, Map<String, String>> getStandard_info_synonym_map() {
        if (standard_info_synonym_map == null) {
            standard_info_synonym_map = NlpCache.getStandard_info_synonym_map();
        }
        return standard_info_synonym_map;
    }

    public static Map<String, String> getDoc_result_mapping_diag_map() {
        if (doc_result_mapping_diag_map == null) {
            createDoc_result_mapping_diag_map();
        }
        return doc_result_mapping_diag_map;
    }

    public static Map<String, String> createDoc_result_mapping_diag_map() {
        Configuration configuration = new DefaultConfig();
        doc_result_mapping_diag_map = configuration.loadMapDict("bigdata_diag_2_dept.dict");
        return doc_result_mapping_diag_map;
    }

    public static Map<String, Map<String, ResultMappingFilter>> getDoc_result_mapping_lpvSex_filter_map() {
        if (doc_result_mapping_lpvSex_filter_map == null) {
            createDoc_result_mapping_lpvSex_filter_map();
        }
        return doc_result_mapping_lpvSex_filter_map;
    }

    public static Map<String, Map<String, ResultMappingFilter>> getDoc_result_mapping_filter_map() {
        if (doc_result_mapping_filter_map == null) {
            createDoc_result_mapping_filter_map();
        }
        return doc_result_mapping_filter_map;
    }

    public static Map<String, Map<String, ResultMappingFilter>> createDoc_result_mapping_filter_map() {
        Configuration configuration = new DefaultConfig();
        List<String> fileContents = configuration.readFileContents("bigdata_sex_age_filter.dict");
        String[] line_string;
        List<ResultMappingFilter> resultMappingFilters = new ArrayList<>();
        try {
            for (int i = 0; i < fileContents.size(); i++) {
                line_string = org.apache.commons.lang3.StringUtils.split(fileContents.get(i), "\\|");
                if (line_string.length == 5) {
                    ResultMappingFilter resultMappingFilter = new ResultMappingFilter();
                    resultMappingFilter.setFeatureName(line_string[0]);
                    resultMappingFilter.setFeatureType(line_string[1]);
                    resultMappingFilter.setSex(line_string[2]);
                    resultMappingFilter.setAgeStart(Integer.parseInt(line_string[3]));
                    resultMappingFilter.setAgeEnd(Integer.parseInt(line_string[4]));
                    resultMappingFilters.add(resultMappingFilter);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        doc_result_mapping_filter_map = new HashMap<>();
        Map<String, ResultMappingFilter> filterMap = null;
        for (ResultMappingFilter resultMappingFilter : resultMappingFilters) {
            filterMap = doc_result_mapping_filter_map.get(resultMappingFilter.getFeatureType());
            if (filterMap == null) {
                filterMap = new HashMap<>();
            }
            filterMap.put(resultMappingFilter.getFeatureName(), resultMappingFilter);
            doc_result_mapping_filter_map.put(resultMappingFilter.getFeatureType(), filterMap);
        }
        return doc_result_mapping_filter_map;
    }

    /**
     * 化验辅检体征年龄性别过滤
     *
     * @return
     */
    public static Map<String, Map<String, ResultMappingFilter>> createDoc_result_mapping_lpvSex_filter_map() {
        Configuration configuration = new DefaultConfig();
        List<String> fileContents = configuration.readFileContents("bigdata_lpv_sex_age_filter.dict");
        String[] line_string;
        List<ResultMappingFilter> resultMappingFilters = new ArrayList<>();
        try {
            for (int i = 0; i < fileContents.size(); i++) {
                line_string = org.apache.commons.lang3.StringUtils.split(fileContents.get(i), "\\|");
                if (line_string.length == 5) {
                    ResultMappingFilter resultMappingFilter = new ResultMappingFilter();
                    resultMappingFilter.setFeatureName(line_string[0]);
                    resultMappingFilter.setFeatureType(line_string[1]);
                    resultMappingFilter.setSex(line_string[2]);
                    resultMappingFilter.setAgeStart(Integer.parseInt(line_string[3]));
                    resultMappingFilter.setAgeEnd(Integer.parseInt(line_string[4]));
                    resultMappingFilters.add(resultMappingFilter);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        doc_result_mapping_lpvSex_filter_map = new HashMap<>();
        Map<String, ResultMappingFilter> filterMap = null;
        for (ResultMappingFilter resultMappingFilter : resultMappingFilters) {
            filterMap = doc_result_mapping_lpvSex_filter_map.get(resultMappingFilter.getFeatureType());
            if (filterMap == null) {
                filterMap = new HashMap<>();
            }
            filterMap.put(resultMappingFilter.getFeatureName(), resultMappingFilter);
            doc_result_mapping_lpvSex_filter_map.put(resultMappingFilter.getFeatureType(), filterMap);
        }
        return doc_result_mapping_lpvSex_filter_map;
    }


    public static Map<String, List<Rule>> getKl_rule_filter_map() {
        if (kl_rule_filter_map == null) {
            create_kl_rule_filter_map();
        }
        return kl_rule_filter_map;
    }

    public static void create_kl_rule_filter_map() {
        kl_rule_filter_map = new HashMap<>();

        Configuration configuration = new DefaultConfig();
        List<String> fileContents = configuration.readFileContents("bigdata_rule_filter.dict");

        List<Rule> rules = null;
        for (String line : fileContents) {
            String[] content = line.split("\\|", -1);
            Rule rule = new Rule();
            if (content.length == 12) {
                rule.setId(content[0] == null ? "" : content[0]);
                rule.setPub_name(content[1] == null ? "" : content[1]);
                rule.setMin_operator(content[2] == null ? "" : content[2]);
                rule.setMin_value(content[3] == null ? "" : content[3]);
                rule.setMin_unit(content[4] == null ? "" : content[4]);
                rule.setMax_operator(content[5] == null ? "" : content[5]);
                rule.setMax_value(content[6] == null ? "" : content[6]);
                rule.setMax_unit(content[7] == null ? "" : content[7]);
                rule.setEq_operator(content[8] == null ? "" : content[8]);
                rule.setEq_value(content[9] == null ? "" : content[9]);
                rule.setEq_unit(content[10] == null ? "" : content[10]);
                rule.setRemind(content[11] == null ? "" : content[11]);
                if (kl_rule_filter_map.get(rule.getPub_name()) == null) {
                    rules = new ArrayList<>();
                } else {
                    rules = kl_rule_filter_map.get(rule.getPub_name());
                }
                rules.add(rule);
                kl_rule_filter_map.put(rule.getPub_name(), rules);
            }
        }
    }

    public static Map<String, RuleApp> getKl_rule_app_filter_map() {
        if (kl_rule_app_filter_map == null) {
            create_kl_rule_app_filter_map();
        }
        return kl_rule_app_filter_map;
    }

    public static void create_kl_rule_app_filter_map() {
        kl_rule_app_filter_map = new HashMap<>();

        Configuration configuration = new DefaultConfig();
        List<String> fileContents = configuration.readFileContents("bigdata_rule_app_filter.dict");

        for (String line : fileContents) {
            String[] content = line.split("\\|", -1);
            RuleApp ruleApp = new RuleApp();
            if (content.length == 4) {
                ruleApp.setId(content[0] == null ? "" : content[0]);
                ruleApp.setRuleIds(content[1] == null ? "" : content[1]);
                ruleApp.setTypeId(content[2] == null ? "" : content[2]);
                ruleApp.setRemind(content[3] == null ? "" : content[3]);
                kl_rule_app_filter_map.put(ruleApp.getId(), ruleApp);
            }
        }
    }

    public static Map<String, Map<String, String>> getKl_diagnose_detail_filter_map() {
        if (kl_diagnose_detail_filter_map == null) {
            create_kl_diagnose_detail_filter_map();
        }
        return kl_diagnose_detail_filter_map;
    }


    public static void create_kl_diagnose_detail_filter_map() {
        kl_diagnose_detail_filter_map = new HashMap<>();
        Map<String, String> diagnoseDetailRelationMap = new HashMap<>();
        Set<String> diagnoseDetailRelation = new HashSet<>();
        Configuration configuration = new DefaultConfig();
        List<String> fileContents = configuration.readFileContents("bigdata_diagnose_detail_filter.dict");
        for (String line : fileContents) {
            String[] content = line.split("\\|", -1);
            String[] relations = content[1].split("、");
            for (String relation : relations) {
                if (diagnoseDetailRelation.add(relation)) {
                    if (kl_diagnose_detail_filter_map.get(content[0]) == null) {
                        diagnoseDetailRelationMap.put(relation, relation);
                        kl_diagnose_detail_filter_map.put(content[0], diagnoseDetailRelationMap);
                    } else {
                        kl_diagnose_detail_filter_map.get(content[0]).put(relation, relation);
                    }
                }
            }
        }
    }

    public static Map<String, Map<String, Float>> getDoc_feature_naivebayes_prob_map() {
        if (doc_feature_naivebayes_prob_map == null) {
            create_doc_feature_naivebayes_prob_map();
        }
        return doc_feature_naivebayes_prob_map;
    }

    public static void create_doc_feature_naivebayes_prob_map() {
        doc_feature_naivebayes_prob_map = new HashMap<>();
        //<rdn,[feature...]> 存储每个rdn对应的特征List
        Map<String, List<String>> featureMap = new HashMap<>();
        List<String> featureList = null;
        Configuration configuration = new DefaultConfig();
        List<String> fileFeatureContents = configuration.readFileContents("bigdata_naivebayes_features.dict");
        for (String line : fileFeatureContents) {
            String[] content = line.split("\\|", -1);
            if (featureMap.get(content[0]) == null) {
                featureList = new ArrayList<>();
                for (String feature : content[1].split(" ")) {
                    featureList.add(feature);
                }
                featureMap.put(content[0], featureList);
            }
        }

        //<rdn,diagnose> 存每个rdn对应疾病
        Map<String, String> diagnoseMap = new HashMap<>();
        //<diagnose,count> 存每个疾病的数量
        Map<String, Integer> diagnoseCount = new HashMap<>();
        List<String> fileDiagnoseContents = configuration.readFileContents("bigdata_naivebayes_diagnose.dict");
        diagnoseCount.put("diagnoseCount", fileDiagnoseContents.size());
        for (String line : fileDiagnoseContents) {
            String[] content = line.split("\\|", -1);
            if (diagnoseMap.get(content[0]) == null) {
                diagnoseMap.put(content[0], content[1]);
            }
            if (diagnoseCount.get(content[1]) == null) {
                diagnoseCount.put(content[1], 1);
            } else {
                diagnoseCount.put(content[1], diagnoseCount.get(content[1]) + 1);
            }
        }

        Map<String, Map<String, Integer>> diagnose2featureCount = new HashMap<>();
        Map<String, Integer> featureCount = new HashMap<>();
        for (Map.Entry<String, String> diagnoseMapEntry : diagnoseMap.entrySet()) {
            //featureMap -> <1000000_144 , [咳嗽,咳痰,1周,气管炎]>
            if (featureMap.get(diagnoseMapEntry.getKey()) == null) {
                continue;
            }
            for (String feature : featureMap.get(diagnoseMapEntry.getKey())) {
                /**
                 diagnoseMapEntry <1596386_9,鼻炎> -> <rdn,diagnose>
                 如果疾病对应特征列表为空 diagnoseMapEntry.getValue()->疾病
                 */
                if (diagnose2featureCount.get(diagnoseMapEntry.getValue()) == null) {
                    featureCount = new HashMap<>();
                    //featureMap -> <1000000_144 , [咳嗽,咳痰,1周,气管炎]>
                    if (featureCount.get(feature) == null) {
                        featureCount.put(feature, 1);
                    } else {
                        featureCount.put(feature, featureCount.get(feature) + 1);
                    }
                    //疾病对应病历数
                    featureCount.put("diagnoseCount", diagnoseCount.get(diagnoseMapEntry.getValue()));
                    diagnose2featureCount.put(diagnoseMapEntry.getValue(), featureCount);
                } else {
                    if (diagnose2featureCount.get(diagnoseMapEntry.getValue()).get(feature) == null) {
                        diagnose2featureCount.get(diagnoseMapEntry.getValue()).put(feature, 1);
                    } else {
                        diagnose2featureCount.get(diagnoseMapEntry.getValue())
                                .put(feature, diagnose2featureCount.get(diagnoseMapEntry.getValue()).get(feature) + 1);
                    }
                }
            }
        }

        Map<String, Float> prob = null;
        for (Map.Entry<String, Map<String, Integer>> diagnose2featureCountEntry : diagnose2featureCount.entrySet()) {
            prob = new HashMap<>();
            //计算先验概率
            float priorProb = (float) diagnose2featureCountEntry.getValue().get("diagnoseCount") / diagnoseCount.get("diagnoseCount");
            prob.put("priorProb", priorProb);
            //计算条件概率
            for (Map.Entry<String, Integer> featuresCount : diagnose2featureCountEntry.getValue().entrySet()) {
                float conditionProb = (float) featuresCount.getValue() / diagnose2featureCountEntry.getValue().get("diagnoseCount");
                prob.put(featuresCount.getKey(), conditionProb);
            }
            doc_feature_naivebayes_prob_map.put(diagnose2featureCountEntry.getKey(), prob);
        }
    }

    public static Map<String, Map<String,Float>> getRelevant_feature_map() {
        if (relevant_feature_bayes_map == null) {
            createRelevant_feature_map();
        }
        return relevant_feature_bayes_map;
    }

    public static Map<String, Map<String,Float>> createRelevant_feature_map() {
        relevant_feature_bayes_map = new HashMap<>();
        Map<String,Float> relevantFeatureProb = null;
        Configuration configuration = new DefaultConfig();
        List<String> relevantFeatureList = configuration.readFileContents("bigdata_relevant_feature.dict");
        for (String relevantFeature:relevantFeatureList) {
            String[] content = relevantFeature.split("\\|", -1);
            if (relevant_feature_bayes_map.get(content[0]) == null){
                relevantFeatureProb = new HashMap<>();
                relevantFeatureProb.put(content[1],0.00f);
                relevant_feature_bayes_map.put(content[0],relevantFeatureProb);
            } else {
                relevant_feature_bayes_map.get(content[0]).put(content[1],0.00f);
            }
        }
        return relevant_feature_bayes_map;
    }

    /**
     * 体征过滤获取对比表信息
     *
     * @return
     */
    public static Map<String, RelevantFeature> get_relevant_feature() {
        if (relevant_feature_map == null) {
            create_get_relevant_feature();
        }
        return relevant_feature_map;
    }

    public static void create_get_relevant_feature(){
        relevant_feature_map = new HashMap<>();
        Configuration configuration = new DefaultConfig();
        List<String> fileContents = configuration.readFileContents("bigdata_diagnose_feature_filter.dict");
        for (String line : fileContents) {
            String[] content = line.split("\\|", -1);
            RelevantFeature relevantFeature = new RelevantFeature();
            if (content.length == 6) {
                relevantFeature.setId(content[0] == null ? "" : content[0]);
                relevantFeature.setDiagnose(content[1] == null ? "" : content[1]);
                relevantFeature.setFeature(content[2] == null ? "" : content[2]);
                relevantFeature.setFeature_type(content[3] == null ? "" : content[3]);
                relevantFeature.setFind_suspect_diagnose(content[4] == null ? "" : content[4]);
                relevantFeature.setValue_type(content[5] == null ? "" : content[5]);
                relevant_feature_map.put(relevantFeature.getDiagnose(),relevantFeature);
            }
        }
    }
}
