package org.diagbot.common.push.cache;

import org.diagbot.pub.jdbc.MysqlJdbc;
import org.diagbot.pub.utils.PropertiesUtil;
import org.diagbot.pub.utils.security.EncrypDES;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.*;

/**
 * Created by louhr on 2019/8/16.
 */
public class CacheFileManager {
    Logger logger = LoggerFactory.getLogger(CacheFileManager.class);

    private String user = "root";
    private String password = "lantone";
    private String url = "jdbc:mysql://192.168.2.236:3306/med?useUnicode=true&characterEncoding=UTF-8";

    private String path = "";

    public static void main(String[] args) {
        CacheFileManager cacheFileManager = new CacheFileManager();
        PropertiesUtil propertiesUtil = new PropertiesUtil("nlp.properties");
        String p = propertiesUtil.getProperty("cache.file.dir");
        File file = new File(p);
        if (!file.exists()) {
            file.mkdirs();
        }
        //自然语言处理
        cacheFileManager.createNlpCacheFile(p);
        //大数据
        cacheFileManager.createBigDataCacheFile(p);
        //图谱
        cacheFileManager.createGraphCacheFile(p);
    }

    public CacheFileManager() {
        PropertiesUtil propertiesUtil = new PropertiesUtil("nlp.properties");
        String p = propertiesUtil.getProperty("cache.file.dir");
        File file = new File(p);
        if (!file.exists()) {
            file.mkdirs();
        }
        logger.info("cache file path...." + p);
        path = p;
    }

    public void createCacheFile() {
        createNlpCacheFile(path);
        createGraphCacheFile(path);
        createBigDataCacheFile(path);
    }

    public void createNlpCacheFile() {
        createNlpCacheFile(path);
    }

    public void createNlpCacheFile(String path) {
        MysqlJdbc nlpJdbc = new MysqlJdbc(user, password, url);
        Connection conn = nlpJdbc.connect();
        Statement st = null;
        ResultSet rs = null;
        try {
            EncrypDES encrypDES = new EncrypDES();
            //所有词典库 不能用concat_group 大小写不区分
            String sql = "select l_1.name l_1_name, l_1.type_id type_id, l_2.name l_2_name, kc.lib_name from kl_library_info l_1\n" +
                    "                    left join kl_library_info l_2 on l_1.concept_id = l_2.concept_id and l_2.is_concept = 1\n" +
                    "left join kl_concept kc on l_1.concept_id = kc.id\n" +
                    "where kc.is_deleted = 'N' ";
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            FileWriter fw = new FileWriter(path + "tc.dict");

            Map<String, String> idMap = new HashMap<>(10);
            Map<String, String> nameMap = new HashMap<>(10);
            String r1;
            String r2;
            String r3;
            while (rs.next()) {
                r1 = rs.getString(1);
                r2 = rs.getString(2);
                r3 = rs.getString(4);
                if (idMap.get(r1) == null) {
                    idMap.put(r1, r2);
                    nameMap.put(r1, r3);
                } else if (idMap.get(r1) != null) {
                    idMap.put(r1, idMap.get(r1) + "," + r2);
                    nameMap.put(r1, nameMap.get(r1) + "," + r3);
                }
            }

            List<Map.Entry<String, String>> libraryList = new ArrayList<Map.Entry<String, String>>(idMap.entrySet());
            Collections.sort(libraryList, new Comparator<Map.Entry<String, String>>() {
                public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
                    return o1.getKey().compareTo(o2.getKey());
                }
            });
            for (Map.Entry<String, String> entry : libraryList) {
                fw.write(encrypDES.encrytor(entry.getKey() + "|9|"
                        + entry.getValue() + "|" + nameMap.get(entry.getKey())));
                fw.write("\n");
            }

            fw.close();

            sql = "SELECT l_1.name l_1_name, l_2.name l_2_name, l_1.type_id FROM kl_library_info l_1 " +
                    "left join kl_library_info l_2 on l_1.concept_id = l_2.concept_id and l_2.is_concept = '1' " +
                    "where l_1.is_concept = '0'";
            st = conn.createStatement();
            rs = st.executeQuery(sql);

            fw = new FileWriter(path + "synonym.dict");
            while (rs.next()) {
                r1 = rs.getString(1);
                r2 = rs.getString(2);
                r3 = rs.getString(3);
                fw.write(encrypDES.encrytor(r1 + "|" + r2 + "|" + r3));
                fw.write("\n");
            }
            fw.close();

            sql = "SELECT l_1.name l_1_name, l_2.name l_2_name FROM kl_relation r " +
                    "left join kl_concept c1 on r.start_id = c1.id " +
                    "left join kl_concept c2 on r.end_id = c2.id " +
                    "left join kl_library_info l_1 on l_1.id = c1.lib_id " +
                    "left join kl_library_info l_2 on l_2.id = c2.lib_id where r.relation_id = 3";
            st = conn.createStatement();
            rs = st.executeQuery(sql);

            libraryList = rsToMap(rs, false);

            fw = new FileWriter(path + "chronic.dict");
            for (Map.Entry<String, String> entry : libraryList) {
                fw.write(encrypDES.encrytor(entry.getKey() + "|" + entry.getValue()));
                fw.write("\n");
            }
            fw.close();

            //推送词典
            sql = "select k1.lib_name k1_lib_name, k2.lib_name k2_lib_name from kl_relation r " +
                    "left join kl_concept k1 on k1.id = r.start_id " +
                    "left join kl_concept k2 on k2.id = r.end_id " +
                    "where r.relation_id = 19 and k1.is_deleted = 'N' and k2.is_deleted = 'N' and k1.lib_type = 1 and k2.lib_type = 1";
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            libraryList = rsToMap(rs, true);

            fw = new FileWriter(path + "push-tc.dict");
            for (Map.Entry<String, String> entry : libraryList) {
                fw.write(encrypDES.encrytor(entry.getKey() + "|" + entry.getValue()));
                fw.write("\n");
            }
            fw.close();

            fw = new FileWriter(path + "classify.dict");
            fw.close();

            sql = "select name, type from kl_library_info_pacs order by name";
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            fw = new FileWriter(path + "pacs-tc.dict");
            while (rs.next()) {
                r1 = rs.getString(1);
                r2 = rs.getString(2);
                fw.write(encrypDES.encrytor(r1 + "|9|"+ r2 + "|" + r1));
                fw.write("\n");
            }
            fw.close();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        } catch (SQLException sqle) {
            sqle.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            nlpJdbc.close(rs, st, conn);
        }
    }

    public void createGraphCacheFile() {
        createGraphCacheFile(path);
    }

    public void createGraphCacheFile(String path) {
        MysqlJdbc nlpJdbc = new MysqlJdbc(user, password, url);
        Connection conn = nlpJdbc.connect();
        Statement st = null;
        ResultSet rs = null;
        try {
            //疾病I、II类
            EncrypDES encrypDES = new EncrypDES();//加密对象
            String sql = "SELECT con.lib_name, dis.classify from kl_disease dis, kl_concept con where dis.concept_id = con.id";
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            FileWriter fw = new FileWriter(path + "graph_diag_classify.dict");
            String r2, r3;
            while (rs.next()) {
                r2 = rs.getString(1);//疾病名称
                r3 = rs.getString(2);//疾病类别
                fw.write(encrypDES.encrytor(r2 + "|" + r3));
                fw.write("\n");
            }
            fw.close();
            //性别年龄
            sql = "SELECT k1.lib_name, k1.lib_type, kcc.sex_type, kcc.min_age, kcc.max_age \n" +
                    "FROM kl_concept_common kcc, kl_concept k1 \n" +
                    "where kcc.concept_id = k1.id \n" +
                    "and k1.lib_type in (18)";
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            fw = new FileWriter(path + "graph_sex_age_filter.dict");
            String r1, r4, r5;
            while (rs.next()) {
                r1 = rs.getString(1);//术语名称
                r2 = rs.getString(3);//sexType 1:男 2:女 3:都可以
                r3 = rs.getString(4);//min_age
                r4 = rs.getString(5);//max_age
                fw.write(encrypDES.encrytor(r1 + "|" + r2 + "|" + r3 + "|" + r4));
                fw.write("\n");
            }
            fw.close();
            //体征结果转体征指标
            sql = "SELECT\n" +
                    "\ti1.lib_name name1,\n" +
                    "\ti2.lib_name name2 \n" +
                    "FROM\n" +
                    "\t`kl_relation` l \n" +
                    "\tLEFT JOIN kl_concept i1 ON l.start_id = i1.id \n" +
                    "\tLEFT JOIN kl_concept i2 ON l.end_id = i2.id \n" +
                    "where l.relation_id=19 AND i1.lib_type=35 AND i2.lib_type=33 AND l.is_deleted='N'";
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            fw = new FileWriter(path + "graph_vital_convert.dict");
            while (rs.next()) {
                r1 = rs.getString(1);//体征结果
                r2 = rs.getString(2);//体征指标
                fw.write(encrypDES.encrytor(r1 + "|" + r2));
                fw.write("\n");
            }
            fw.close();
            //疾病科室信息
            sql = "SELECT k1.lib_name diag_name, k2.lib_name dept_name FROM kl_disease kcc, kl_concept k1, kl_concept k2 " +
                    "where kcc.concept_id = k1.id and kcc.dept_id = k2.id " +
                    "and k1.lib_type = 18 and kcc.dept_id  is not null";
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            List<Map.Entry<String, String>> libaryList = rsToMap(rs, true);
            fw = new FileWriter(path + "graph_diag_2_dept.dict");
            for (Map.Entry<String, String> entry : libaryList) {
                fw.write(encrypDES.encrytor(entry.getKey() + "|" + entry.getValue()));
                fw.write("\n");
            }
            fw.close();

            sql = "SELECT g.diag_level1,g.diag_level2,g.diag_level3 FROM `kl_disease_normalize` g ";
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            fw = new FileWriter(path + "graph_diag_normalize.dict");
            while (rs.next()) {
                r1 = rs.getString(1);
                r2 = rs.getString(2);
                r3 = rs.getString(3);
                fw.write(encrypDES.encrytor(r1 + "|" + r2 + "|" + r3));
                fw.write("\n");
            }
            fw.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            nlpJdbc.close(rs, st, conn);
        }
    }

    public void createBigDataCacheFile() {
        createBigDataCacheFile(path);
    }

    public void createBigDataCacheFile(String path) {
        MysqlJdbc nlpJdbc = new MysqlJdbc(user, password, url);
        Connection conn = nlpJdbc.connect();
        Statement st = null;
        ResultSet rs = null;
        try {
            EncrypDES encrypDES = new EncrypDES();
            //疾病科室
            String sql = "SELECT k1.lib_name diag_name, k2.lib_name dept_name FROM kl_disease kcc, kl_concept k1, kl_concept k2 " +
                    "where kcc.concept_id = k1.id and kcc.dept_id = k2.id " +
                    "and k1.lib_type = 18 and kcc.dept_id  is not null";
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            List<Map.Entry<String, String>> libraryList = rsToMap(rs, true);

            FileWriter fw = new FileWriter(path + "bigdata_diag_2_dept.dict");
            for (Map.Entry<String, String> entry : libraryList) {
                fw.write(encrypDES.encrytor(entry.getKey() + "|" + entry.getValue()));
                fw.write("\n");
            }
            fw.close();

            //性别年龄
            sql = "SELECT k1.lib_name, k1.lib_type, kcc.sex_type, kcc.min_age, kcc.max_age " +
                    "FROM kl_concept_common kcc, kl_concept k1 " +
                    "where kcc.concept_id = k1.id " +
                    "and k1.lib_type in (1, 18)";
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            fw = new FileWriter(path + "bigdata_sex_age_filter.dict");

            String r1, r2, r3, r4, r5;
            while (rs.next()) {
                r1 = rs.getString(1);
                r2 = rs.getString(2);
                r3 = rs.getString(3);
                r4 = rs.getString(4);
                r5 = rs.getString(5);
                if ("18".equals(r2)) {
                    r2 = "2";
                }
                fw.write(encrypDES.encrytor(r1 + "|" + r2 + "|" + r3 + "|" + r4 + "|" + r5));
                fw.write("\n");
            }
            fw.close();

            sql = "SELECT lib_name FROM kl_concept WHERE is_deleted = 'N' AND lib_type = 70 AND lib_name regexp '[0-9]'";
            st = conn.createStatement();
            rs = st.executeQuery(sql);

            fw = new FileWriter(path + "bigdata_value_analyze.dict");
            while (rs.next()) {
                fw.write(encrypDES.encrytor(rs.getString(1)));
                fw.write("\n");
            }
            fw.close();

            //规则过滤信息
            sql = "SELECT id, pub_name, min_operator, min_value, min_unit, max_operator, max_value, " +
                    "max_unit, eq_operator, eq_value, eq_unit, remind FROM kl_rule_pub";
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            fw = new FileWriter(path + "bigdata_rule_filter.dict");
            String r6, r7, r8, r9, r10, r11, r12;
            while (rs.next()) {
                r1 = String.valueOf(rs.getInt(1));
                r2 = rs.getString(2);
                r3 = rs.getString(3);
                r4 = rs.getString(4);
                r5 = rs.getString(5);
                r6 = rs.getString(6);
                r7 = rs.getString(7);
                r8 = rs.getString(8);
                r9 = rs.getString(9);
                r10 = rs.getString(10);
                r11 = rs.getString(11);
                r12 = rs.getString(12);
                r1 = StringUtils.isEmpty(r1) ? "" : r1;
                r2 = StringUtils.isEmpty(r2) ? "" : r2;
                r3 = StringUtils.isEmpty(r3) ? "" : r3;
                r4 = StringUtils.isEmpty(r4) ? "" : r4;
                r5 = StringUtils.isEmpty(r5) ? "" : r5;
                r6 = StringUtils.isEmpty(r6) ? "" : r6;
                r7 = StringUtils.isEmpty(r7) ? "" : r7;
                r8 = StringUtils.isEmpty(r8) ? "" : r8;
                r9 = StringUtils.isEmpty(r9) ? "" : r9;
                r10 = StringUtils.isEmpty(r10) ? "" : r10;
                r11 = StringUtils.isEmpty(r11) ? "" : r11;
                r12 = StringUtils.isEmpty(r12) ? "" : r12;
                fw.write(encrypDES.encrytor(r1 + "|" + r2 + "|" + r3 + "|" + r4 + "|" + r5
                        + "|" + r6 + "|" + r7 + "|" + r8 + "|" + r9 + "|" + r10 + "|" + r11
                        + "|" + r12));
                fw.write("\n");
            }
            fw.close();

            sql = "SELECT id, rule_id, rule_type, remind FROM kl_rule_app";
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            fw = new FileWriter(path + "bigdata_rule_app_filter.dict");
            while (rs.next()) {
                r1 = String.valueOf(rs.getInt(1));
                r2 = rs.getString(2);
                r3 = rs.getString(3);
                r4 = rs.getString(4);
                r1 = StringUtils.isEmpty(r1) ? "" : r1;
                r2 = StringUtils.isEmpty(r2) ? "" : r2;
                r3 = StringUtils.isEmpty(r3) ? "" : r3;
                r4 = StringUtils.isEmpty(r4) ? "" : r4;
                fw.write(encrypDES.encrytor(r1 + "|" + r2 + "|" + r3 + "|" + r4));
                fw.write("\n");
            }
            fw.close();

            sql = "SELECT type,relation FROM `kl_diagnose_detail` WHERE type = 4 AND LENGTH(relation) > 0 GROUP BY relation";
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            fw = new FileWriter(path + "bigdata_diagnose_detail_filter.dict");
            while (rs.next()) {
                r1 = String.valueOf(rs.getInt(1));
                r2 = rs.getString(2);
                fw.write(encrypDES.encrytor(r1+ "|" + r2));
                fw.write("\n");
            }
            fw.close();

            sql = "SELECT rdn, GROUP_CONCAT(feature_name ORDER BY sn SEPARATOR ' ') AS features FROM doc_feature WHERE feature_type = 9 GROUP BY rdn;";
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            fw = new FileWriter(path + "bigdata_naivebayes_features.dict");
            while (rs.next()) {
                r1 = rs.getString(1);
                r2 = rs.getString(2);
                fw.write(encrypDES.encrytor(r1+ "|" + r2));
                fw.write("\n");
            }
            fw.close();

            sql = "select rdn, feature_name as diagnose from doc_feature where feature_type=2";
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            fw = new FileWriter(path + "bigdata_naivebayes_diagnose.dict");
            while (rs.next()) {
                r1 = rs.getString(1);
                r2 = rs.getString(2);
                fw.write(encrypDES.encrytor(r1+ "|" + r2));
                fw.write("\n");
            }
            fw.close();

            sql = "SELECT diagnose,feature FROM doc_relevant_feature;";
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            fw = new FileWriter(path + "bigdata_relevant_feature.dict");
            while (rs.next()) {
                r1 = rs.getString(1);
                r2 = rs.getString(2);
                fw.write(encrypDES.encrytor(r1+ "|" + r2));
                fw.write("\n");
            }
            fw.close();

            //化验辅检体征性别年龄
            sql = "SELECT k1.lib_name, k1.lib_type, kcc.sex_type, kcc.min_age, kcc.max_age " +
                    "FROM kl_concept_common kcc, kl_concept k1 " +
                    "where kcc.concept_id = k1.id " +
                    "and k1.lib_type in (1, 18,12,16,33,35)";
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            fw = new FileWriter(path + "bigdata_lpv_sex_age_filter.dict");//化验辅检体征相关文件
            while (rs.next()) {
                r1 = rs.getString(1);
                r2 = rs.getString(2);
                r3 = rs.getString(3);
                r4 = rs.getString(4);
                r5 = rs.getString(5);
                if ("18".equals(r2)) {//诊断
                    r2 = "2";
                }
                if ("12".equals(r2)) {//化验
                    r2 = "4";
                }
                if ("16".equals(r2)) {//辅检
                    r2 = "5";
                }
                if ("33".equals(r2) | "35".equals(r2)) {//体征
                    r2 = "3";
                }
                fw.write(encrypDES.encrytor(r1 + "|" + r2 + "|" + r3 + "|" + r4 + "|" + r5));
                fw.write("\n");
            }
            fw.close();

            //特征提取过滤参照表信息
            sql = "SELECT id,diagnose,feature,feature_type,value_type,find_suspect_diagnose FROM `doc_relevant_feature`";
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            fw = new FileWriter(path + "bigdata_diagnose_feature_filter.dict");
            while (rs.next()) {
                r1 = String.valueOf(rs.getInt(1));
                r2 = rs.getString(2);
                r3 = rs.getString(3);
                r4 = rs.getString(4);
                r5 = rs.getString(5);
                r6 = rs.getString(6);
                r1 = StringUtils.isEmpty(r1) ? "" : r1;
                r2 = StringUtils.isEmpty(r2) ? "" : r2;
                r3 = StringUtils.isEmpty(r3) ? "" : r3;
                r4 = StringUtils.isEmpty(r4) ? "" : r4;
                r5 = StringUtils.isEmpty(r5) ? "" : r5;
                r6 = StringUtils.isEmpty(r6) ? "" : r6;
                fw.write(encrypDES.encrytor(r1 + "|" + r2 + "|" + r3 + "|" + r4 + "|" + r5
                        + "|" + r6 ));
                fw.write("\n");
            }
            fw.close();

        } catch (IOException ioe) {
            ioe.printStackTrace();
        } catch (SQLException sqle) {
            sqle.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            nlpJdbc.close(rs, st, conn);
        }
    }

    private List<Map.Entry<String, String>> rsToMap(ResultSet rs, boolean isJoin) throws SQLException {
        String r1 = "";
        String r2 = "";
        Map<String, String> libraryMap = new HashMap<>(10);
        while (rs.next()) {
            r1 = rs.getString(1);
            r2 = rs.getString(2);
            if (libraryMap.get(r1) == null) {
                libraryMap.put(r1, r2);
            } else if (isJoin && libraryMap.get(r1) != null) {
                libraryMap.put(r1, libraryMap.get(r1) + "," + r2);
            }
        }

        List<Map.Entry<String, String>> libraryList = new ArrayList<Map.Entry<String, String>>(libraryMap.entrySet());
        Collections.sort(libraryList, new Comparator<Map.Entry<String, String>>() {
            public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
                return o1.getKey().compareTo(o2.getKey());
            }
        });

        return libraryList;
    }
}
