package com.palacesun.masking.tools;

import com.palacesun.engine.gateway.EncryptionGatewayManager;
import com.palacesun.engine.gateway.util.GatewaySocketLogUtil;
import com.palacesun.engine.maskingtool.ExpressionTool;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.palacesun.masking.entity.orm.table.core.strategy.audit.conditions.AuditApplicationConditions;
import com.palacesun.masking.entity.orm.table.core.strategy.audit.conditions.AuditDateConditions;
import com.palacesun.masking.entity.orm.table.core.strategy.audit.conditions.AuditDbuserConditions;
import com.palacesun.masking.entity.orm.table.core.strategy.audit.conditions.AuditIpConditions;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.stat.TableStat;
import com.palacesun.masking.adapter.DateTime;
import com.palacesun.masking.adapter.DateUtil;
import com.palacesun.masking.adapter.ObjectUtil;
import com.palacesun.masking.adapter.StringUtils;
import com.palacesun.masking.tools.ruleload.RuleLoadUtil;
import com.palacesun.masking.vo.Columninfo;
import com.palacesun.masking.vo.ConnectionInfo;
import com.palacesun.masking.vo.JsonRootBean;
import com.palacesun.masking.vo.TableInfo;
import com.palacesun.masking.vo.masking.MaskingColumnInfo;
import com.palacesun.masking.vo.masking.MaskingRootBean;
import com.palacesun.masking.vo.masking.MaskingTableInfo;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import util.sqlparse.visitor.common.Objects;

public class EngineUtil {
   public static final String KEY_FROM_CACHE = "1";
   public static final String KEY_FROM_FILE = "2";
   public static final List<MaskingRootBean> authBeanList = new ArrayList();
   public static final List<JsonRootBean> encryptonBeanList = new ArrayList();
   public static final List<JsonRootBean> digestBeanList = new ArrayList();
   private static ExpressionTool et = null;
   public static final Map<String, Object> maskingmap = new HashMap();
   public static Map<String, Object> encryptionUDFMap = new HashMap();
   public static Map<String, Object> encryptionMap = new HashMap();
   public static Set<String> encryptionTableSet = new HashSet();
   public static Set<Columninfo> encryptionSet = new HashSet();
   public static Map<String, Object> digestMap = new HashMap();
   public static Map<String, Object> digestMapBak = new HashMap();
   public static ThreadLocal<String> ip = new ThreadLocal();

   public static void initRule() {
      try {
         encryptonBeanList.clear();
         authBeanList.clear();
         encryptionRuleToBean();
         digestRuleToBean();

         try {
            maskingRuleToBean();
         } catch (Exception var1) {
         }

      } catch (Throwable ex) {
         System.err.println("Initial masking.properties failed." + ex);
         throw new ExceptionInInitializerError(ex);
      }
   }

   private static void digestRuleToBean() {
      synchronized(digestMap) {
         Map<String, Object> digestMapTemp = new HashMap();
         ArrayList<JSONArray> authList = null;
         if (RuleLoadUtil.isEncryptionRuleFromGateway()) {
            authList = RuleLoadUtil.loadDigestRuleFromGateway();
         } else {
            authList = AuthUtil.toArrayByEncryptionFileReader();
         }

         if (authList != null) {
            for(JSONArray authArray : authList) {
               for(Object key : authArray) {
                  new JsonRootBean();
                  new ArrayList();
                  JsonRootBean jsonRootBean = (JsonRootBean)JSON.parseObject(((JSONObject)key).toString(), JsonRootBean.class);
                  List<TableInfo> tableinfoList = jsonRootBean.getTableInfo();
                  if (tableinfoList != null && tableinfoList.size() != 0) {
                     for(int i = 0; i < tableinfoList.size(); ++i) {
                        List<Columninfo> fieldinfoList = ((TableInfo)tableinfoList.get(i)).getColumninfo();
                        String maskingTablename = ((TableInfo)tableinfoList.get(i)).getTablename();
                        String maskingSchema = jsonRootBean.getSchema();
                        String dbip = jsonRootBean.getDbip();
                        String dbport = jsonRootBean.getDbport();

                        for(int j = 0; j < fieldinfoList.size(); ++j) {
                           Boolean flag = false;
                           Columninfo fieldinfo = (Columninfo)fieldinfoList.get(j);
                           String maskingColumnname = fieldinfo.getColumnname();
                           digestMapTemp.put((dbip + "@@" + dbport + "@@" + maskingSchema + "@@" + maskingTablename + "@@" + maskingColumnname).toLowerCase(), fieldinfo);
                        }
                     }

                     digestBeanList.add(jsonRootBean);
                  }
               }
            }
         }

         String keyLocation = EncryptionGatewayManager.getParameterValue("encryption.keyCache");
         if (digestMapTemp != null && !digestMapTemp.isEmpty()) {
            digestMap = digestMapTemp;
            if (Objects.equals(keyLocation, "2") && StringUtils.isNotEmpty(RuleLoadUtil.digestRuleStr) && !RuleLoadUtil.digestRuleStr.contains("OOW_01")) {
               GatewaySocketLogUtil.writeDigestKeyCache(RuleLoadUtil.digestRuleStr);
            }
         } else if (Objects.equals(keyLocation, "2")) {
            keyCacheFromFile();
         } else {
            digestMap = digestMapTemp;
         }

         for(Map.Entry<String, Object> entry : digestMap.entrySet()) {
            digestMapBak.put(((String)entry.getKey()).replace("@@", "_"), entry.getValue());
         }

      }
   }

   public static Object dataEngine(String tableName, String columnName, Object value, String schema, ConnectionInfo connectionInfo) throws Exception {
      return value;
   }

   private static void maskingRuleToBean() {
      ArrayList<JSONArray> authList = null;
      if (RuleLoadUtil.isMaskingRuleFromGateway()) {
         authList = RuleLoadUtil.loadMaskingRuleFromGateway();
      } else {
         authList = AuthUtil.toArrayByMaskingFileReader();
      }

      authBeanList.clear();
      maskingmap.clear();

      for(JSONArray authArray : authList) {
         for(Object key : authArray) {
            new MaskingRootBean();
            new ArrayList();
            MaskingRootBean jsonRootBean = (MaskingRootBean)JSON.parseObject(((JSONObject)key).toString(), MaskingRootBean.class);
            List<MaskingTableInfo> tableinfoList = jsonRootBean.getTableInfo();
            if (tableinfoList != null && tableinfoList.size() != 0) {
               for(int i = 0; i < tableinfoList.size(); ++i) {
                  List<MaskingColumnInfo> fieldinfoList = ((MaskingTableInfo)tableinfoList.get(i)).getColumninfo();
                  String maskingTablename = ((MaskingTableInfo)tableinfoList.get(i)).getTablename();
                  String maskingSchema = jsonRootBean.getSchema();
                  String dbip = jsonRootBean.getDbip();
                  String dbport = jsonRootBean.getDbport();

                  for(int j = 0; j < fieldinfoList.size(); ++j) {
                     Boolean flag = false;
                     MaskingColumnInfo fieldinfo = (MaskingColumnInfo)fieldinfoList.get(j);
                     String maskingColumnname = fieldinfo.getColumnname();
                     System.out.println(dbip + "_" + dbport + "_" + maskingSchema + "_" + maskingTablename + "_" + maskingColumnname);
                     maskingmap.put((dbip + "_" + dbport + "_" + maskingSchema + "_" + maskingTablename + "_" + maskingColumnname).toLowerCase(), fieldinfo);
                  }
               }

               authBeanList.add(jsonRootBean);
            }
         }
      }

   }

   private static void encryptionRuleToBean() {
      synchronized(encryptionMap) {
         Map<String, Object> encryptionMapTemp = new HashMap();
         Map<String, Object> encryptionUDFMapTemp = new HashMap();
         HashSet encryptionSetTemp = new HashSet();
         ArrayList<JSONArray> authList = null;
         if (RuleLoadUtil.isEncryptionRuleFromGateway()) {
            authList = RuleLoadUtil.loadEncryptionRuleFromGateway();
         } else {
            authList = AuthUtil.toArrayByEncryptionFileReader();
         }

         if (authList != null) {
            for(JSONArray authArray : authList) {
               for(Object key : authArray) {
                  new JsonRootBean();
                  new ArrayList();
                  JsonRootBean jsonRootBean = (JsonRootBean)JSON.parseObject(((JSONObject)key).toString(), JsonRootBean.class);
                  List<TableInfo> tableinfoList = jsonRootBean.getTableInfo();
                  if (tableinfoList != null && tableinfoList.size() != 0) {
                     for(int i = 0; i < tableinfoList.size(); ++i) {
                        List<Columninfo> fieldinfoList = ((TableInfo)tableinfoList.get(i)).getColumninfo();
                        String maskingTablename = ((TableInfo)tableinfoList.get(i)).getTablename();
                        encryptionTableSet.add(maskingTablename.toLowerCase());
                        String maskingSchema = jsonRootBean.getSchema();
                        String dbip = jsonRootBean.getDbip();
                        String dbport = jsonRootBean.getDbport();

                        for(int j = 0; j < fieldinfoList.size(); ++j) {
                           Boolean flag = false;
                           Columninfo fieldinfo = (Columninfo)fieldinfoList.get(j);
                           String maskingColumnname = fieldinfo.getColumnname();
                           encryptionMapTemp.put((dbip + "_" + dbport + "_" + maskingSchema + "_" + maskingTablename + "_" + maskingColumnname).toLowerCase(), fieldinfo);
                           if (EncryptionGatewayManager.checkParameterFlag("encryption.query.udf")) {
                              HashMap<String, String> secretMap = new HashMap(16);
                              String secretKey = fieldinfo.getSecretkey();
                              String encryptionType = fieldinfo.getEncryptiontype();
                              if (secretKey != null && !secretKey.equals("")) {
                                 secretMap.put("key", secretKey);
                                 secretMap.put("type", encryptionType);
                                 encryptionUDFMapTemp.put(maskingSchema.toUpperCase() + "&&" + maskingTablename.toUpperCase() + "&&" + maskingColumnname.toUpperCase(), secretMap);
                              }
                           }

                           Columninfo clone = fieldinfo.clone();
                           clone.setKeepfirst("0");
                           clone.setEncdigit("0");
                           clone.setTwoindex("0");
                           encryptionSetTemp.add(clone);
                        }
                     }

                     encryptonBeanList.add(jsonRootBean);
                     encryptionSet.clear();
                     encryptionSet.addAll(encryptionSetTemp);
                  }
               }
            }
         }

         if (encryptonBeanList.size() == 0) {
            EncryptionGatewayManager.logClientError("拉取加密规则为空");
         }

         if (EncryptionGatewayManager.checkParameterFlag("encryption.query.udf")) {
            encryptionUDFMap = encryptionUDFMapTemp;
         }

         String keyLocation = EncryptionGatewayManager.getParameterValue("encryption.keyCache");
         if (encryptionMapTemp != null && !encryptionMapTemp.isEmpty()) {
            encryptionMap = encryptionMapTemp;
            if (Objects.equals(keyLocation, "2") && StringUtils.isNotEmpty(RuleLoadUtil.encryptionRuleStr) && !RuleLoadUtil.encryptionRuleStr.contains("OOW_01")) {
               GatewaySocketLogUtil.writeKeyCache(RuleLoadUtil.encryptionRuleStr);
            }
         } else if (Objects.equals(keyLocation, "2")) {
            keyCacheFromFile();
         }

      }
   }

   public static Boolean verifyStrategy(ConnectionInfo conInfo, JsonRootBean keyObject, Boolean flag) {
      return flag;
   }

   private static Boolean matchTime(Boolean flag, List<AuditDateConditions> dateconditionslist) {
      if (ObjectUtil.isEmpty(dateconditionslist)) {
         return flag;
      } else {
         if (flag) {
            for(int k = 0; k < dateconditionslist.size(); ++k) {
               AuditDateConditions datecs = (AuditDateConditions)dateconditionslist.get(k);

               try {
                  String format = "yyyy/MM/dd HH:mm";
                  Date now = new DateTime();
                  Date startTime = (new SimpleDateFormat(format)).parse(datecs.getStarttime());
                  Date endTime = (new SimpleDateFormat(format)).parse(datecs.getEndtime());
                  if (DateUtil.isIn(now, startTime, endTime)) {
                     flag = true;
                  } else {
                     flag = false;
                  }
               } catch (ParseException e) {
                  e.printStackTrace();
               }
            }
         }

         return flag;
      }
   }

   private static Boolean matchDb(ConnectionInfo conInfo, JsonRootBean keyObject, Boolean flag) {
      return flag;
   }

   private static Boolean matchIp(Boolean flag, List<AuditIpConditions> ipconditionslist, String clientIp) {
      if (StringUtils.isBlank(clientIp)) {
         return false;
      } else if (ObjectUtil.isEmpty(ipconditionslist)) {
         return true;
      } else {
         for(AuditIpConditions ipcs : ipconditionslist) {
            if (ipcs.getMatchsymbol().equals("=")) {
               if (clientIp.equals(ipcs.getMatchval())) {
                  flag = true;
                  break;
               }

               flag = false;
            } else if (ipcs.getMatchsymbol().equals("<>")) {
               if (!clientIp.equals(ipcs.getMatchval())) {
                  flag = true;
                  break;
               }

               flag = false;
            } else if (ipcs.getMatchsymbol().equals("=%")) {
               if (RequestUtil.ipIsValid(ipcs.getStartval(), ipcs.getEndval(), clientIp)) {
                  flag = true;
                  break;
               }

               flag = false;
            } else if (ipcs.getMatchsymbol().equals("<>%")) {
               if (!RequestUtil.ipIsValid(ipcs.getStartval(), ipcs.getEndval(), clientIp)) {
                  flag = true;
                  break;
               }

               flag = false;
            }
         }

         return flag;
      }
   }

   public static Object exeOutEngine(String mathKey, Object ret, Boolean encFlag) throws Exception {
      Columninfo map = (Columninfo)encryptionMap.get(mathKey);
      return exeEngine(map, (ConnectionInfo)null, false, ret, encFlag);
   }

   public static Object exeEngine(Columninfo fieldinfo, ConnectionInfo conInfo, Boolean flag, Object ret, Boolean enc2decrypt) throws Exception {
      String encryptiontype = fieldinfo.getEncryptiontype();
      String key = fieldinfo.getSecretkey();
      String isLike = fieldinfo.getIsLike();
      String keepfirst = fieldinfo.getKeepfirst();
      String encdigit = fieldinfo.getEncdigit();
      String twoindex = fieldinfo.getTwoindex();

      try {
         if (ret instanceof ArrayList) {
            ArrayList arrayList = (ArrayList)ret;
            if (arrayList.size() > 0) {
               for(int m = 0; m < arrayList.size(); ++m) {
                  if (arrayList.get(m) instanceof SQLCharExpr) {
                     ((SQLCharExpr)arrayList.get(m)).setText(ReflectUtil.engine(encryptiontype, ((SQLCharExpr)arrayList.get(m)).getText(), key, isLike, keepfirst, encdigit, twoindex, enc2decrypt, fieldinfo));
                  }
               }
            }
         } else {
            long start = System.nanoTime();
            ret = ReflectUtil.engine(encryptiontype, (String)ret, key, isLike, keepfirst, encdigit, twoindex, enc2decrypt, fieldinfo);
         }

         return ret;
      } catch (Exception var13) {
         return ret;
      }
   }

   private static String generateTemeplateString(String jsonStr, String value) {
      jsonStr = jsonStr.replaceAll("\\$\\{".concat("value").concat("\\}"), "\\'" + value + "\\'");
      return jsonStr;
   }

   private static Boolean matchUser(ConnectionInfo conInfo, Boolean flag, List<AuditDbuserConditions> dbuserconditionslist) {
      if (conInfo != null && StringUtils.isBlank(conInfo.getUserName())) {
         return false;
      } else if (ObjectUtil.isEmpty(dbuserconditionslist)) {
         return flag;
      } else {
         if (flag) {
            for(AuditDbuserConditions dbusercs : dbuserconditionslist) {
               if (dbusercs.getMatchsymbol().equals("=")) {
                  if (conInfo.getUserName().equals(dbusercs.getMatchval())) {
                     flag = true;
                     break;
                  }

                  flag = false;
               } else if (dbusercs.getMatchsymbol().equals("<>")) {
                  if (!conInfo.getUserName().equals(dbusercs.getMatchval())) {
                     flag = true;
                     break;
                  }

                  flag = false;
               }
            }
         }

         return flag;
      }
   }

   private static Boolean matchApplication(Boolean flag, com.palacesun.masking.vo.Map jsonObjectMap, String clientUsername) {
      List<AuditApplicationConditions> applicationconditionslist = jsonObjectMap.getApplicationConditions();
      if (ObjectUtil.isEmpty(applicationconditionslist)) {
         return flag;
      } else {
         if (flag) {
            for(AuditApplicationConditions appcs : applicationconditionslist) {
               if (appcs.getMatchsymbol().equals("=")) {
                  if (clientUsername.equalsIgnoreCase(appcs.getMatchval())) {
                     flag = true;
                     break;
                  }

                  flag = false;
               } else if (appcs.getMatchsymbol().equals("<>")) {
                  if (!clientUsername.equalsIgnoreCase(appcs.getMatchval())) {
                     flag = true;
                     break;
                  }

                  flag = false;
               }
            }
         }

         return flag;
      }
   }

   private static String doMasking(String sql, Map<String, Object> ruleinfo) {
      StringBuffer sb = new StringBuffer("");
      Collection<TableStat.Column> tablefieldList = SqlParseTool.getColumns(sql);
      if (tablefieldList.isEmpty()) {
         return sql;
      } else {
         String desensitizationexpression = (String)ruleinfo.get("desensitizationexpression");
         String tablename = (String)ruleinfo.get("tablename");
         String columnname = (String)ruleinfo.get("columnname");

         for(TableStat.Column tablefield : tablefieldList) {
            if (tablefield.getTable().equals(tablename) && tablefield.getName().equals(columnname)) {
               sb.setLength(0);
               sb.append(sql.replaceFirst(tablefield.getName(), desensitizationexpression));
            }
         }

         return sb.toString();
      }
   }

   public static Object exeMaskingEngine(MaskingColumnInfo map, Object value) {
      String expression = map.getExpression();

      try {
         value = ExpressionTool.masking(value, expression);
         return value;
      } catch (Exception e) {
         e.printStackTrace();
         return value;
      }
   }

   public static void keyCacheFromFile() {
      String keyCache = EncryptionGatewayManager.getParameterValue("encryption.keyCache");
      if (keyCache != null && !"".equals(keyCache) && !"1".equals(keyCache)) {
         Map<String, Object> encryptionMapTemp = new HashMap();

         for(JSONArray authArray : AuthUtil.toArrayByEncryptionFileReaderFromRoot()) {
            for(Object key : authArray) {
               JsonRootBean jsonRootBean = (JsonRootBean)JSON.parseObject(((JSONObject)key).toString(), JsonRootBean.class);
               List<TableInfo> tableinfoList = jsonRootBean.getTableInfo();

               for(int i = 0; i < tableinfoList.size(); ++i) {
                  List<Columninfo> fieldinfoList = ((TableInfo)tableinfoList.get(i)).getColumninfo();
                  String maskingTablename = ((TableInfo)tableinfoList.get(i)).getTablename();
                  String maskingSchema = jsonRootBean.getSchema();
                  String dbip = jsonRootBean.getDbip();
                  String dbport = jsonRootBean.getDbport();

                  for(int j = 0; j < fieldinfoList.size(); ++j) {
                     Columninfo fieldinfo = (Columninfo)fieldinfoList.get(j);
                     String maskingColumnname = fieldinfo.getColumnname();
                     encryptionMapTemp.put((dbip + "_" + dbport + "_" + maskingSchema + "_" + maskingTablename + "_" + maskingColumnname).toLowerCase(), fieldinfo);
                  }
               }

               authBeanList.clear();
               encryptonBeanList.add(jsonRootBean);
            }
         }

         encryptionMap = encryptionMapTemp;
      }
   }

   static {
      EncryptionGatewayManager.loadProperties();

      for(int i = 0; i < 3; ++i) {
         try {
            initRule();
            break;
         } catch (Exception e) {
            e.printStackTrace();
         }
      }

      try {
         Thread.sleep(1000L);
         new EncryptionGatewayManager();
      } catch (InterruptedException e) {
         e.printStackTrace();
      }

   }
}
