package com.chenyang.nse.bussiness.tools.strategy;

import com.alibaba.fastjson.JSONObject;
import com.chenyang.nse.bussiness.ccoresdf.CcoreSDFUtil;
import com.chenyang.nse.bussiness.config.PropertiesLoaderUtils;
import com.chenyang.nse.bussiness.dao.core.key.TCoreKeyTypeManagementDao;
import com.chenyang.nse.bussiness.dao.table.base.TBaseRoleDao;
import com.chenyang.nse.bussiness.dao.table.base.TBaseUserroleDao;
import com.chenyang.nse.bussiness.dao.table.core.TCoreDatasystemDao;
import com.chenyang.nse.bussiness.dao.table.core.dataproject.TCoreSecretkeyDao;
import com.chenyang.nse.bussiness.dao.table.core.encryption.DesensitizationStrategyDao;
import com.chenyang.nse.bussiness.dao.table.core.encryption.TCoreDigestMainDao;
import com.chenyang.nse.bussiness.dao.table.core.encryption.TCoreEncryptionDao;
import com.chenyang.nse.bussiness.dao.table.core.encryption.TCoreEncryptionTypeFieldDao;
import com.chenyang.nse.bussiness.dao.table.core.file.TCoreFileStructurecolumnDao;
import com.chenyang.nse.bussiness.dao.table.core.masking.TCoreDesensitizationRuleDao;
import com.chenyang.nse.bussiness.encryptor.service.impl.TCoreEncryptionServiceSdkImpl;
import com.chenyang.nse.bussiness.entity.orm.table.base.TBaseRole;
import com.chenyang.nse.bussiness.entity.orm.table.base.TBaseUserrole;
import com.chenyang.nse.bussiness.entity.orm.table.core.TCoreDatasystem;
import com.chenyang.nse.bussiness.entity.orm.table.core.TCoreDigestMain;
import com.chenyang.nse.bussiness.entity.orm.table.core.dataproject.TCoreSecretkey;
import com.chenyang.nse.bussiness.entity.orm.table.core.encryption.TCoreDesensitizationStrategy;
import com.chenyang.nse.bussiness.entity.orm.table.core.encryption.TCoreEncryption;
import com.chenyang.nse.bussiness.entity.orm.table.core.encryption.TCoreEncryptionTypeField;
import com.chenyang.nse.bussiness.entity.orm.table.core.file.TCoreFileStructurecolumn;
import com.chenyang.nse.bussiness.entity.orm.table.core.masking.TCoreDesensitizationRule;
import com.chenyang.nse.bussiness.kms.service.KmsService;
import com.chenyang.nse.bussiness.service.core.impl.encryption.TCoreEncryptionServiceImpl;
import com.chenyang.nse.bussiness.thkms.service.ThKmsService;
import com.chenyang.nse.bussiness.tools.dataprocess.ApplicationContextProvider;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;
import org.apache.shiro.codec.Hex;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

@Component
public class StrategyData {
   @Autowired
   private TCoreEncryptionTypeFieldDao tCoreEncryptionTypeFieldDao;
   @Autowired
   DesensitizationStrategyDao desensitizationStrategyDao;
   @Autowired
   private TCoreDatasystemDao tCoreDatasystemDao;
   @Autowired
   private TCoreSecretkeyDao tCoreSecretkeyDao;
   @Autowired
   private TCoreEncryptionDao tCoreEncryptionDao;
   @Autowired
   TCoreDesensitizationRuleDao tCoreDesensitizationRuleDao;
   @Autowired
   private TBaseRoleDao tBaseRoleDao;
   @Autowired
   private TBaseUserroleDao tBaseUserroleDao;
   @Autowired
   ThKmsService thKmsService;
   @Autowired
   KmsService kmsService;
   @Autowired(
      required = false
   )
   TCoreEncryptionServiceSdkImpl tCoreEncryptionServiceSdkImpl;
   @Autowired
   TCoreKeyTypeManagementDao tCoreKeyTypeManagementDao;
   @Autowired
   TCoreDigestMainDao tCoreDigestMainDao;
   @Autowired
   TCoreFileStructurecolumnDao tCoreFileStructurecolumnDao;

   public String getEncryptionData(String projectid, String... flag) {
      List<TCoreEncryptionTypeField> tCoreEncryptionTypeFieldByProject = null;
      Properties props = null;

      try {
         props = PropertiesLoaderUtils.loadAllProperties("config.properties");
      } catch (IOException e) {
         e.printStackTrace();
      }

      String isPullAll = props.getProperty("is_pull_all");
      if ("1".equals(isPullAll)) {
         tCoreEncryptionTypeFieldByProject = this.tCoreEncryptionTypeFieldDao.queryAll(new Criterion[]{Restrictions.in("flag", flag)});
      } else if ("0".equals(isPullAll)) {
         if (projectid != null && !projectid.equals("")) {
            tCoreEncryptionTypeFieldByProject = this.tCoreEncryptionTypeFieldDao.queryAll(new Criterion[]{Restrictions.eq("projectid", projectid), Restrictions.in("flag", flag)});
         } else {
            tCoreEncryptionTypeFieldByProject = this.tCoreEncryptionTypeFieldDao.queryAll(new Criterion[]{Restrictions.in("flag", flag)});
         }
      }

      Map<String, List<TCoreEncryptionTypeField>> collect = (Map)tCoreEncryptionTypeFieldByProject.stream().collect(Collectors.groupingBy((x) -> x.getDatasystem_id() + "." + x.getTschemas()));
      List<EncryptionInfoVo> list = (List)collect.keySet().stream().map((key) -> {
         EncryptionInfoVo vo = new EncryptionInfoVo();
         String[] split = key.split("\\.");
         TCoreDatasystem tCoreDatasystem = (TCoreDatasystem)this.tCoreDatasystemDao.queryUnique(new Criterion[]{Restrictions.eq("id", split[0])});
         if (null != tCoreDatasystem) {
            vo.setDatasystemid(split[0]);
            vo.setSchema(split[1]);
            vo.setDbip(tCoreDatasystem.getDbip());
            vo.setDbport(tCoreDatasystem.getDbport());
            vo.setDbservername(tCoreDatasystem.getDbservername());
            vo.setDbtype(tCoreDatasystem.getDbtype());
            Map<String, List<TCoreEncryptionTypeField>> groupTabelMap = (collect.get(key)).stream().collect(Collectors.groupingBy((x) -> x.getNames()));
            List<TableInfoVo> tableList = (List)groupTabelMap.keySet().stream().map((tkey) -> {
               TableInfoVo tableInfoVo = new TableInfoVo();
               tableInfoVo.setTablename(tkey);
               List<TCoreEncryptionTypeField> tCoreEncryptionTypeFields = (List)groupTabelMap.get(tkey);
               List<ColumnInfoVo> columnInfoList = new ArrayList();

               for(TCoreEncryptionTypeField x : tCoreEncryptionTypeFields) {
                  ColumnInfoVo columnInfoVo = new ColumnInfoVo();
                  columnInfoVo.setId(x.getId());
                  switch (tCoreDatasystem.getDbtype()) {
                     case "KAFKA":
                        TCoreFileStructurecolumn tCoreFileStructurecolumn = (TCoreFileStructurecolumn)this.tCoreFileStructurecolumnDao.queryUnique(new Criterion[]{Restrictions.eq("id", x.getTable_field_id())});
                        columnInfoVo.setColumnname(String.valueOf(tCoreFileStructurecolumn.getColumnindex()));
                        break;
                     default:
                        columnInfoVo.setColumnname(x.getTable_field_id());
                  }

                  columnInfoVo.setColumnType(x.getColumn_type());
                  TCoreSecretkey tCoreSecretkey = (TCoreSecretkey)this.tCoreSecretkeyDao.queryUnique(new Criterion[]{Restrictions.eq("id", x.getEncryption_secretkey_id())});
                  if (tCoreSecretkey != null) {
                     TCoreEncryption tCoreEncryption = (TCoreEncryption)this.tCoreEncryptionDao.queryUnique(new Criterion[]{Restrictions.eq("id", tCoreSecretkey.getEncryption_id())});
                     columnInfoVo.setEncryptiontype(tCoreEncryption.getEncryption_type());
                     TCoreEncryptionServiceImpl tCoreEncryptionServiceImpl = (TCoreEncryptionServiceImpl)ApplicationContextProvider.getBean(TCoreEncryptionServiceImpl.class);
                     String dateKey = tCoreEncryptionServiceImpl.getDecDataKey(tCoreSecretkey.getSectet_key_value());
                     columnInfoVo.setSecretkey(dateKey);
                     columnInfoVo.setIsLike(x.getIslike());
                     columnInfoVo.setKeepfirst(x.getKeepfirst());
                     columnInfoVo.setEncdigit(x.getEncdigit());
                     columnInfoVo.setTwoindex(x.getTwoindex());
                     columnInfoList.add(columnInfoVo);
                  }
               }

               tableInfoVo.setColumninfo(columnInfoList);
               return tableInfoVo;
            }).collect(Collectors.toList());
            vo.setTableInfo(tableList);
         }

         return vo;
      }).collect(Collectors.toList());
      List<EncryptionInfoVo> eiVoList = (List)list.stream().filter((eiVo) -> eiVo.getDatasystemid() != null && !eiVo.getDatasystemid().isEmpty() || eiVo.getSchema() != null && !eiVo.getSchema().isEmpty() || eiVo.getDbip() != null && !eiVo.getDbip().isEmpty() || eiVo.getDbport() != null && !eiVo.getDbport().isEmpty() || eiVo.getDbservername() != null && !eiVo.getDbservername().isEmpty()).collect(Collectors.toList());
      return JSONObject.toJSONString(eiVoList);
   }

   public String getDigestData(String projectid) {
      List<TCoreDigestMain> tCoreDigestMainList = null;
      Properties props = null;

      try {
         props = PropertiesLoaderUtils.loadAllProperties("config.properties");
      } catch (IOException e) {
         e.printStackTrace();
      }

      String isPullAll = props.getProperty("is_pull_all");
      String digestkey = props.getProperty("digestkey");
      if ("1".equals(isPullAll)) {
         tCoreDigestMainList = this.tCoreDigestMainDao.queryAll(new Criterion[]{Restrictions.in("flag", new Object[]{"1"})});
      } else if ("0".equals(isPullAll)) {
         if (projectid != null && !projectid.equals("")) {
            tCoreDigestMainList = this.tCoreDigestMainDao.queryAll(new Criterion[]{Restrictions.eq("projectid", projectid), Restrictions.in("flag", new Object[]{"1"})});
         } else {
            tCoreDigestMainList = this.tCoreDigestMainDao.queryAll(new Criterion[]{Restrictions.in("flag", new Object[]{"1"})});
         }
      }

      tCoreDigestMainList = (List)tCoreDigestMainList.stream().filter((x) -> !StringUtils.isEmpty(x.getDigestfield())).collect(Collectors.toList());
      Map<String, List<TCoreDigestMain>> collect = (Map)tCoreDigestMainList.stream().collect(Collectors.groupingBy((x) -> x.getDatasystemid() + "." + x.getSchemaname()));
      List<DigestInfoVo> list = (List)collect.keySet().stream().map((key) -> {
         DigestInfoVo vo = new DigestInfoVo();
         String[] split = key.split("\\.");
         TCoreDatasystem tCoreDatasystem = (TCoreDatasystem)this.tCoreDatasystemDao.queryUnique(new Criterion[]{Restrictions.eq("id", split[0])});
         if (null != tCoreDatasystem) {
            vo.setDatasystemid(split[0]);
            vo.setSchema(split[1]);
            vo.setDbip(tCoreDatasystem.getDbip());
            vo.setDbport(tCoreDatasystem.getDbport());
            vo.setDbservername(tCoreDatasystem.getDbservername());
            Map<String, List<TCoreDigestMain>> groupTabelMap = (collect.get(key)).stream().collect(Collectors.groupingBy((x) -> x.getTablename()));
            List<TableInfoVo> tableList = (List)groupTabelMap.keySet().stream().map((tkey) -> {
               TableInfoVo tableInfoVo = new TableInfoVo();
               tableInfoVo.setTablename(tkey);
               List<TCoreDigestMain> tCoreDigestMains = (List)groupTabelMap.get(tkey);
               List<ColumnInfoVo> columnInfoList = new ArrayList();

               for(TCoreDigestMain x : tCoreDigestMains) {
                  String[] digests = x.getDigestfield().split("#");

                  for(int i = 0; i < digests.length; ++i) {
                     ColumnInfoVo columnInfoVo = new ColumnInfoVo();
                     columnInfoVo.setId(x.getId());
                     columnInfoVo.setColumnname(digests[i]);
                     columnInfoVo.setEncryptiontype("SM3");
                     columnInfoVo.setSecretkey(digestkey);
                     columnInfoList.add(columnInfoVo);
                  }
               }

               tableInfoVo.setColumninfo(columnInfoList);
               return tableInfoVo;
            }).collect(Collectors.toList());
            vo.setTableInfo(tableList);
         }

         return vo;
      }).collect(Collectors.toList());
      return JSONObject.toJSONString(list);
   }

   public String queryCcoreSDFKey(String key) {
      try {
         if (null != key && !"".equals(key)) {
            try {
               byte[] endData = Hex.decode(key);
               return CcoreSDFUtil.getDecrypt(endData);
            } catch (Exception e) {
               e.printStackTrace();
            }
         }

         return "加密卡解密秘钥失败";
      } catch (Exception exception) {
         return "加密卡解密秘钥失败," + exception.toString();
      }
   }

   public String getDesensitizationStrategy(String projectid, String state) {
      List<TCoreDesensitizationStrategy> tCoreDesenByProject = null;
      if (projectid != null && !projectid.equals("")) {
         tCoreDesenByProject = this.desensitizationStrategyDao.queryAll(new Criterion[]{Restrictions.eq("projectid", projectid), Restrictions.eq("state", state)});
      } else {
         tCoreDesenByProject = this.desensitizationStrategyDao.queryAll(new Criterion[]{Restrictions.eq("state", state)});
      }

      Map<String, List<TCoreDesensitizationStrategy>> collect = (Map)tCoreDesenByProject.stream().collect(Collectors.groupingBy((x) -> x.getDatasystem_id() + "." + x.getTschemas()));
      List<EncryptionDesensitizationVo> list = (List)collect.keySet().stream().map((key) -> {
         EncryptionDesensitizationVo vo = new EncryptionDesensitizationVo();
         String[] split = key.split("\\.");
         TCoreDatasystem tCoreDatasystem = (TCoreDatasystem)this.tCoreDatasystemDao.queryUnique(new Criterion[]{Restrictions.eq("id", split[0])});
         if (null != tCoreDatasystem) {
            vo.setDatasystemid(split[0]);
            vo.setSchema(split[1]);
            vo.setDbip(tCoreDatasystem.getDbip());
            vo.setDbport(tCoreDatasystem.getDbport());
            vo.setDbservername(tCoreDatasystem.getDbservername());
            Map<String, List<TCoreDesensitizationStrategy>> groupTabelMap = (collect.get(key)).stream().collect(Collectors.groupingBy((x) -> x.getNames()));
            List<TableDesensitizationVo> tableList = (List)groupTabelMap.keySet().stream().map((tkey) -> {
               TableDesensitizationVo tableDesensitizationVo = new TableDesensitizationVo();
               tableDesensitizationVo.setTablename(tkey);
               List<TCoreDesensitizationStrategy> TCoreDesensitizationStrategys = (List)groupTabelMap.get(tkey);
               List<ColumnInDesensitizationVo> columnInfoList = (List)TCoreDesensitizationStrategys.stream().map((x) -> {
                  ColumnInDesensitizationVo columnInDesensitizationVo = new ColumnInDesensitizationVo();
                  columnInDesensitizationVo.setColumnname(x.getTable_field_id());
                  List<String> userIdList = new ArrayList();
                  List<String> roleIdList = new ArrayList();
                  if (null != x.getRolegroup()) {
                     String roleGroupList1 = x.getRolegroup();
                     if (roleGroupList1.trim().equals("")) {
                        Criterion croleid = Restrictions.ne("id", "1");
                        List<TBaseRole> tBaseRolelist = this.tBaseRoleDao.queryAll(new Criterion[]{croleid});
                        StringBuffer roleGroupSB = new StringBuffer();
                        int tB = tBaseRolelist.size();
                        if (tB > 0) {
                           for(int t = 0; t < tB; ++t) {
                              String rolename = ((TBaseRole)tBaseRolelist.get(t)).getRolename();
                              if (StringUtils.hasText(rolename)) {
                                 roleGroupSB.append(rolename).append(",");
                              }
                           }
                        }

                        String roleGroup1 = roleGroupSB.toString().substring(0, roleGroupSB.lastIndexOf(","));
                        x.setRolegroup(roleGroup1);
                     }

                     String roleGroup = "";
                     String[] roleGroupList = x.getRolegroup().split(",");
                     int p = roleGroupList.length;
                     if (p > 0) {
                        for(int i = 0; i < p; ++i) {
                           roleGroup = roleGroupList[i];
                           if (null != roleGroup && !"".equals(roleGroup)) {
                              List<TBaseRole> tBaseRoleList = this.tBaseRoleDao.queryAll(new Criterion[]{Restrictions.eq("rolename", roleGroup)});
                              int y = tBaseRoleList.size();
                              if (y > 0) {
                                 String roleId = ((TBaseRole)tBaseRoleList.get(0)).getId();
                                 if (null != roleId && !"".equals(roleId)) {
                                    roleIdList.add(roleId);
                                 }
                              }
                           }
                        }
                     }
                  }

                  int h = roleIdList.size();
                  if (h > 0) {
                     for(int yy = 0; yy < h; ++yy) {
                        String roleId1 = (String)roleIdList.get(yy);
                        if (null != roleId1 && !"".equals(roleId1)) {
                           List<TBaseUserrole> tBaseUserroleList = this.tBaseUserroleDao.queryAll(new Criterion[]{Restrictions.eq("roleid", roleId1)});
                           int t = tBaseUserroleList.size();
                           if (t > 0) {
                              for(int n = 0; n < t; ++n) {
                                 String userId = ((TBaseUserrole)tBaseUserroleList.get(n)).getUserid();
                                 if (null != userId && !"".equals(userId)) {
                                    userIdList.add(userId);
                                 }
                              }
                           }
                        }
                     }
                  }

                  columnInDesensitizationVo.setUserIdList(userIdList);
                  String expression = "";
                  if (null != x.getRuleid() && !"".equals(x.getRuleid()) && null != this.tCoreDesensitizationRuleDao.get(x.getRuleid())) {
                     String expression1 = ((TCoreDesensitizationRule)this.tCoreDesensitizationRuleDao.get(x.getRuleid())).getExpression();
                     if (null != expression1 && !"".equals(expression1)) {
                        expression = expression1;
                     }
                  }

                  columnInDesensitizationVo.setExpression(expression);
                  return columnInDesensitizationVo;
               }).collect(Collectors.toList());
               tableDesensitizationVo.setColumninfo(columnInfoList);
               return tableDesensitizationVo;
            }).collect(Collectors.toList());
            vo.setTableInfo(tableList);
         }

         return vo;
      }).collect(Collectors.toList());
      if (list.size() > 0) {
         int pp = list.size();

         for(int p = 0; p < pp; ++p) {
            if (null == ((EncryptionDesensitizationVo)list.get(p)).getDbip() || null == ((EncryptionDesensitizationVo)list.get(p)).getDbport() || null == ((EncryptionDesensitizationVo)list.get(p)).getDbservername()) {
               list.remove(p);
            }
         }
      }

      return JSONObject.toJSONString(list);
   }

   public static void main(String[] args) {
      List<Map<String, String>> list = new ArrayList();
      Map<String, String> map = new HashMap();
      map.put("id", "1");
      map.put("schema", "aa");
      map.put("tablename", "user");
      map.put("columnname", "name");
      map.put("key", "111");
      map.put("value", "222");
      list.add(map);
      Map<String, String> map1 = new HashMap();
      map1.put("id", "2");
      map1.put("schema", "bb");
      map1.put("tablename", "dept");
      map1.put("columnname", "name");
      map1.put("key", "111");
      map1.put("value", "222");
      list.add(map1);
      Map<String, String> map3 = new HashMap();
      map3.put("id", "1");
      map3.put("schema", "aa");
      map3.put("tablename", "dept");
      map3.put("columnname", "name");
      map3.put("key", "111");
      map3.put("value", "222");
      list.add(map3);
      Map<String, List<Map<String, String>>> collect = (Map)list.stream().collect(Collectors.groupingBy((x) -> (String)x.get("id") + "." + (String)x.get("schema")));
   }
}
