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

import ch.qos.logback.classic.Logger;
import com.chenyang.nse.bussiness.config.PropertiesLoaderUtils;
import com.chenyang.nse.bussiness.entity.orm.table.core.TCoreDatasystem;
import com.chenyang.nse.bussiness.entity.vo.maskingtask.ColumnInfoVO;
import com.chenyang.nse.bussiness.enumeration.EdbType;
import com.chenyang.nse.bussiness.tools.encryption.EncUtils;
import com.chenyang.nse.bussiness.tools.jdbc.JdbcTool;
import com.chenyang.nse.bussiness.tools.jdbc.MongodbTool;
import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
import java.io.IOException;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.Set;
import org.bson.Document;
import org.bson.conversions.Bson;

public class EncryptProcessUtil {
   private static Properties properties;
   private static String ENCRYPT_LABEL;
   private static String MONGODBPK;

   public static void rollbackColumnLength(Connection con, Logger encryptionlogger, com.chenyang.nse.bussiness.entity.vo.strategy.ColumnInfoVO c, TCoreDatasystem tCoreDatasystem, String schema, String tableName, List<ColumnInfoVO> allColumnList) throws SQLException {
      if (!"STRING".equals(c.getColumnType().toUpperCase(Locale.ROOT)) && !"CLOB".equals(c.getColumnType().toUpperCase(Locale.ROOT))) {
         if (!tCoreDatasystem.getDbtype().equals(EdbType.MYSQL.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.MARIADB.toString()) || !"TEXT".equalsIgnoreCase(c.getColumnType())) {
            if (tCoreDatasystem.getDbtype().equals(EdbType.HIVE_TDH.toString())) {
               String sql = "alter table " + schema + "." + tableName + " change " + c.getColumnName() + " " + c.getColumnName() + " " + c.getColumnType();
               String columnSize = c.getRealitycolumnsize();
               columnSize = "(" + columnSize + ")";
               sql = sql + columnSize;
               PreparedStatement preStatement = con.prepareStatement(sql);
               preStatement.executeUpdate();
               preStatement.close();
               if (null != sql) {
                  encryptionlogger.info("回滚原列长度完成：  sql语句：" + sql);
               }

            } else if (tCoreDatasystem.getDbtype().equals(EdbType.MSSQLSERVER.toString())) {
               String sql = "alter table " + schema + "." + tableName + " alter column " + c.getColumnName() + " " + c.getColumnType();
               String columnSize = c.getRealitycolumnsize();
               columnSize = "(" + columnSize + ")";
               sql = sql + columnSize;
               PreparedStatement preStatement = con.prepareStatement(sql);
               preStatement.executeUpdate();
               preStatement.close();
               con.commit();
               if (null != sql) {
                  encryptionlogger.info("回滚原列长度完成：  sql语句：" + sql);
               }

            } else {
               StringBuilder alterSqlBuilder = new StringBuilder();
               if (!tCoreDatasystem.getDbtype().equals(EdbType.MYSQL.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.DB2.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.MARIADB.toString())) {
                  if (!tCoreDatasystem.getDbtype().equals(EdbType.GREENPLUM.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.POSTGRESQL.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.GAUSSDB.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.KINGBASE.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.GAUSS.toString())) {
                     if (tCoreDatasystem.getDbtype().equals(EdbType.DM.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.ORACLE.toString())) {
                        alterSqlBuilder.append("alter table \"").append(schema).append("\".\"").append(tableName).append("\" modify ( ");
                     }
                  } else {
                     alterSqlBuilder.append("alter table \"").append(schema).append("\".\"").append(tableName).append("\"");
                  }
               } else {
                  alterSqlBuilder.append("alter table ").append(schema).append(".").append(tableName);
               }

               String columnSize = c.getRealitycolumnsize();
               columnSize = "(" + columnSize + ")";
               ColumnInfoVO columnInfoVO = (ColumnInfoVO)allColumnList.stream().filter((cvo) -> c.getColumnName().equals(cvo.getColumnname())).findFirst().get();
               String remark = columnInfoVO.getRemarks();
               if (!tCoreDatasystem.getDbtype().equals(EdbType.MYSQL.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.MARIADB.toString())) {
                  if (tCoreDatasystem.getDbtype().equals(EdbType.GREENPLUM.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.POSTGRESQL.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.GAUSSDB.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.KINGBASE.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.GAUSS.toString())) {
                     alterSqlBuilder.append(" alter column \"").append(c.getColumnName()).append("\" type ").append(c.getColumnType()).append(columnSize);
                  }
               } else {
                  alterSqlBuilder.append(" modify ").append(c.getColumnName()).append(" ").append(c.getColumnType()).append(columnSize);
                  alterSqlBuilder.append(" comment '").append(remark).append("' ");
               }

               if (!tCoreDatasystem.getDbtype().equals(EdbType.DM.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.ORACLE.toString())) {
                  if (tCoreDatasystem.getDbtype().equals(EdbType.DB2.toString())) {
                     alterSqlBuilder.append(" alter column ").append(c.getColumnName()).append(" ").append(" set data type ").append(c.getColumnType()).append(columnSize);
                  }
               } else {
                  alterSqlBuilder.append(" \"").append(c.getColumnName()).append("\" ").append(c.getColumnType()).append(columnSize);
               }

               if (tCoreDatasystem.getDbtype().equals(EdbType.DM.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.ORACLE.toString())) {
                  alterSqlBuilder.append(")");
               }

               String alterSql = alterSqlBuilder.toString();
               if ("DB2".equals(tCoreDatasystem.getDbtype())) {
                  CallableStatement cs = con.prepareCall("call SYSPROC.ADMIN_CMD('reorg table " + schema + "." + tableName + "')");
                  cs.execute();
                  cs.close();
               }

               PreparedStatement preStatement = con.prepareStatement(alterSql);
               preStatement.executeUpdate();
               preStatement.close();
               if ("DB2".equals(tCoreDatasystem.getDbtype())) {
                  CallableStatement cs = con.prepareCall("call SYSPROC.ADMIN_CMD('reorg table " + schema + "." + tableName + "')");
                  cs.execute();
                  cs.close();
               }

               if (tCoreDatasystem.getDbtype().equals(EdbType.GREENPLUM.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.POSTGRESQL.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.GAUSSDB.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.GAUSS.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.KINGBASE.toString())) {
                  con.commit();
               }

               if (null != alterSql) {
                  encryptionlogger.info("回滚原列长度完成：  sql语句：" + alterSql);
               }

            }
         }
      }
   }

   public static void rollBackColumn(Connection connection, Logger encryptionlogger, com.chenyang.nse.bussiness.entity.vo.strategy.ColumnInfoVO columnInfoVO, TCoreDatasystem tCoreDatasystem, String schema, String tableName, String copySuffix) throws SQLException {
      StringBuilder backUpSqlBuilder = new StringBuilder();
      if (!EdbType.MYSQL.toString().equals(tCoreDatasystem.getDbtype()) && !EdbType.MSSQLSERVER.toString().equals(tCoreDatasystem.getDbtype()) && !EdbType.HIVE.toString().equals(tCoreDatasystem.getDbtype()) && !EdbType.HIVE_TDH.toString().equals(tCoreDatasystem.getDbtype())) {
         if (EdbType.ORACLE.toString().equals(tCoreDatasystem.getDbtype()) || EdbType.POSTGRESQL.toString().equals(tCoreDatasystem.getDbtype()) || EdbType.GREENPLUM.toString().equals(tCoreDatasystem.getDbtype()) || tCoreDatasystem.getDbtype().equals(EdbType.GAUSSDB.toString()) || EdbType.DM.toString().equals(tCoreDatasystem.getDbtype()) || EdbType.KINGBASE.toString().equals(tCoreDatasystem.getDbtype()) || EdbType.GAUSS.toString().equals(tCoreDatasystem.getDbtype())) {
            backUpSqlBuilder.append(" update \"").append(schema).append("\".\"").append(tableName).append("\" set ");
            backUpSqlBuilder.append("\"").append(columnInfoVO.getColumnName()).append("\" = \"").append(columnInfoVO.getColumnName() + copySuffix).append("\",");
         }
      } else {
         backUpSqlBuilder.append(" update ").append(schema).append(".").append(tableName).append(" set ");
         backUpSqlBuilder.append(columnInfoVO.getColumnName()).append(" = ").append(columnInfoVO.getColumnName() + copySuffix).append(",");
      }

      if (backUpSqlBuilder.length() > 0) {
         backUpSqlBuilder = backUpSqlBuilder.deleteCharAt(backUpSqlBuilder.length() - 1);
      }

      String backUpSql = backUpSqlBuilder.toString();
      PreparedStatement preStatement = connection.prepareStatement(backUpSql);
      preStatement.executeUpdate();
      preStatement.close();
      if (null != backUpSql) {
         encryptionlogger.info("回滚原列数据完成：  sql语句：" + backUpSql);
      }

   }

   public static void backUpAllCopyColumn(Connection connection, Logger encryptionlogger, TCoreDatasystem tCoreDatasystem, List<com.chenyang.nse.bussiness.entity.vo.strategy.ColumnInfoVO> columnInfoList, String schema, String tableName, String copySuffix, ColumnInfoVO pkey) throws SQLException {
      Set<String> columnMap = JdbcTool.getColumnMap(connection, schema, tableName);
      int count = 0;

      for(com.chenyang.nse.bussiness.entity.vo.strategy.ColumnInfoVO columnInfoVO : columnInfoList) {
         if (columnMap.contains(columnInfoVO.getColumnName() + copySuffix)) {
            ++count;
         }
      }

      if (count != 0) {
         String db2PrimaryKey = "";
         StringBuilder backUpSqlBuilder = new StringBuilder();
         if (!EdbType.MYSQL.toString().equals(tCoreDatasystem.getDbtype()) && !EdbType.MSSQLSERVER.toString().equals(tCoreDatasystem.getDbtype()) && !EdbType.HIVE.toString().equals(tCoreDatasystem.getDbtype()) && !EdbType.HIVE_TDH.toString().equals(tCoreDatasystem.getDbtype()) && !EdbType.OCEANBASE.toString().equals(tCoreDatasystem.getDbtype()) && !EdbType.MARIADB.toString().equals(tCoreDatasystem.getDbtype())) {
            if (EdbType.ORACLE.toString().equals(tCoreDatasystem.getDbtype()) || EdbType.POSTGRESQL.toString().equals(tCoreDatasystem.getDbtype()) || EdbType.GREENPLUM.toString().equals(tCoreDatasystem.getDbtype()) || EdbType.DM.toString().equals(tCoreDatasystem.getDbtype()) || EdbType.KINGBASE.toString().equals(tCoreDatasystem.getDbtype()) || EdbType.GAUSS.toString().equals(tCoreDatasystem.getDbtype()) || tCoreDatasystem.getDbtype().equals(EdbType.GAUSSDB.toString()) || EdbType.DB2.toString().equals(tCoreDatasystem.getDbtype())) {
               backUpSqlBuilder.append(" update \"").append(schema).append("\".\"").append(tableName).append("\" set ");

               for(com.chenyang.nse.bussiness.entity.vo.strategy.ColumnInfoVO columnInfoVO : columnInfoList) {
                  if (columnMap.contains(columnInfoVO.getColumnName() + copySuffix)) {
                     backUpSqlBuilder.append("\"").append(columnInfoVO.getColumnName() + copySuffix).append("\" = \"").append(columnInfoVO.getColumnName()).append("\",");
                  }
               }
            }
         } else {
            backUpSqlBuilder.append(" update ").append(schema).append(".").append(tableName).append(" set ");

            for(com.chenyang.nse.bussiness.entity.vo.strategy.ColumnInfoVO columnInfoVO : columnInfoList) {
               if (columnMap.contains(columnInfoVO.getColumnName() + copySuffix)) {
                  backUpSqlBuilder.append(columnInfoVO.getColumnName() + copySuffix).append(" = ").append(columnInfoVO.getColumnName()).append(",");
               }
            }
         }

         if (backUpSqlBuilder.length() > 0) {
            backUpSqlBuilder = backUpSqlBuilder.deleteCharAt(backUpSqlBuilder.length() - 1);
         }

         if (!EdbType.DB2.toString().equals(tCoreDatasystem.getDbtype())) {
            String backUpSql = backUpSqlBuilder.toString();
            PreparedStatement preStatement = connection.prepareStatement(backUpSql);
            preStatement.executeUpdate();
            preStatement.close();
            if (null != backUpSql) {
               encryptionlogger.info("备份原列数据完成：  sql语句：" + backUpSql);
            }

         } else {
            String countSql = "select count(1) as table_count from " + schema + "." + tableName;
            Statement statement = connection.createStatement();
            ResultSet res = statement.executeQuery(countSql);

            int var37;
            for(int countInt = 0; res.next(); var37 = res.getInt("table_count")) {
            }

            int step = 1;
            int base = 2000;
            int offset = 0;
            String min = "";
            String max = "";
            db2PrimaryKey = pkey.getColumnname();
            String selectMinSql = "select " + db2PrimaryKey + " from " + schema + "." + tableName + " order by " + db2PrimaryKey + " limit 1";

            for(ResultSet selectMinRes = statement.executeQuery(selectMinSql); selectMinRes.next(); min = selectMinRes.getString(db2PrimaryKey)) {
            }

            if (min == "") {
               statement.execute(backUpSqlBuilder.toString());
               statement.close();
            } else {
               do {
                  max = "";
                  offset = step * base;
                  String selectSql = "select " + db2PrimaryKey + " from " + schema + "." + tableName + " order by " + db2PrimaryKey + " limit 1 offset " + offset;
                  StringBuilder db2Builder = new StringBuilder();
                  db2Builder.append(" update \"").append(schema).append("\".\"").append(tableName).append("\" set ");

                  for(com.chenyang.nse.bussiness.entity.vo.strategy.ColumnInfoVO columnInfoVO : columnInfoList) {
                     if (columnMap.contains(columnInfoVO.getColumnName() + copySuffix)) {
                        db2Builder.append("\"").append(columnInfoVO.getColumnName() + copySuffix).append("\" = \"").append(columnInfoVO.getColumnName()).append("\",");
                     }
                  }

                  if (db2Builder.length() > 0) {
                     db2Builder = db2Builder.deleteCharAt(db2Builder.length() - 1);
                  }

                  statement = connection.createStatement();

                  for(ResultSet selectRes = statement.executeQuery(selectSql); selectRes.next(); max = selectRes.getString(db2PrimaryKey)) {
                  }

                  db2Builder.append(" where ").append(db2PrimaryKey).append(" >= ").append("'" + min + "'");
                  if (!max.equals("")) {
                     db2Builder.append(" and ").append(db2PrimaryKey).append(" <= ").append("'" + max + "'");
                  }

                  statement.execute(db2Builder.toString());
                  min = max;
                  ++step;
                  statement.close();
               } while(!max.equals(""));

            }
         }
      }
   }

   public static void addAllColumnLength(Connection con, Logger encryptionlogger, TCoreDatasystem tCoreDatasystem, List<com.chenyang.nse.bussiness.entity.vo.strategy.ColumnInfoVO> columnInfoList, String schema, String tableName, List<ColumnInfoVO> allColumn) throws SQLException {
      int max = 0;

      try {
         Properties properties = PropertiesLoaderUtils.loadAllProperties("config.properties");
         String property = properties.getProperty("encryption.field.max");
         if (property != null && property.length() > 0) {
            max = Integer.valueOf(property.trim());
         }
      } catch (Exception e) {
         e.printStackTrace();
      }

      if (tCoreDatasystem.getDbtype().equals(EdbType.HIVE_TDH.toString())) {
         List<String> sqlList = new ArrayList();

         for(com.chenyang.nse.bussiness.entity.vo.strategy.ColumnInfoVO c : columnInfoList) {
            if (!"STRING".equals(c.getColumnType().toUpperCase(Locale.ROOT)) && !"CLOB".equals(c.getColumnType().toUpperCase(Locale.ROOT))) {
               String sql = "alter table " + schema + "." + tableName + " change " + c.getColumnName() + " " + c.getColumnName() + " " + c.getColumnType();
               String columnSize = c.getColumnSize();
               if (max > 0 && Integer.parseInt(columnSize) >= max) {
                  columnSize = String.valueOf(max);
               } else {
                  columnSize = EncUtils.strColumnSize(tCoreDatasystem.getDbtype(), c.getColumnType(), c.getColumnSize(), c.getIsLike(), "0", c.getEncryptionType());
               }

               if (!"STRING".toUpperCase(Locale.ROOT).equals(c.getColumnType())) {
                  columnSize = "(" + columnSize + ")";
                  sql = sql + columnSize;
               }

               sqlList.add(sql);
            }
         }

         for(String s : sqlList) {
            PreparedStatement preStatement = con.prepareStatement(s);
            preStatement.executeUpdate();
            preStatement.close();
            if (null != s) {
               encryptionlogger.info("扩展原列长度完成：  sql语句：" + s);
            }
         }

      } else if (tCoreDatasystem.getDbtype().equals(EdbType.MSSQLSERVER.toString())) {
         List<String> sqlList = new ArrayList();

         for(com.chenyang.nse.bussiness.entity.vo.strategy.ColumnInfoVO c : columnInfoList) {
            if (!"STRING".equals(c.getColumnType().toUpperCase(Locale.ROOT)) && !"CLOB".equals(c.getColumnType().toUpperCase(Locale.ROOT))) {
               String sql = "alter table " + schema + "." + tableName + " alter column " + c.getColumnName() + " " + c.getColumnType();
               String columnSize = c.getColumnSize();
               if (max > 0 && Integer.parseInt(columnSize) >= max) {
                  columnSize = String.valueOf(max);
               } else {
                  columnSize = EncUtils.strColumnSize(tCoreDatasystem.getDbtype(), c.getColumnType(), c.getColumnSize(), c.getIsLike(), "0", c.getEncryptionType());
               }

               columnSize = "(" + columnSize + ")";
               sql = sql + columnSize;
               sqlList.add(sql);
            }
         }

         for(String s : sqlList) {
            PreparedStatement preStatement = con.prepareStatement(s);
            preStatement.executeUpdate();
            preStatement.close();
            if (null != s) {
               encryptionlogger.info("扩展原列长度完成：  sql语句：" + s);
            }
         }

      } else {
         StringBuilder alterSqlBuilder = new StringBuilder();
         if (!tCoreDatasystem.getDbtype().equals(EdbType.MYSQL.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.OCEANBASE.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.DB2.toString()) && !EdbType.MARIADB.toString().equals(tCoreDatasystem.getDbtype())) {
            if (!tCoreDatasystem.getDbtype().equals(EdbType.GREENPLUM.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.POSTGRESQL.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.KINGBASE.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.GAUSS.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.GAUSSDB.toString())) {
               if (tCoreDatasystem.getDbtype().equals(EdbType.DM.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.ORACLE.toString())) {
                  alterSqlBuilder.append("alter table \"").append(schema).append("\".\"").append(tableName).append("\" modify ( ");
               }
            } else {
               alterSqlBuilder.append("alter table \"").append(schema).append("\".\"").append(tableName).append("\"");
            }
         } else {
            alterSqlBuilder.append("alter table ").append(schema).append(".").append(tableName);
         }

         for(com.chenyang.nse.bussiness.entity.vo.strategy.ColumnInfoVO c : columnInfoList) {
            ColumnInfoVO columnInfoVO = (ColumnInfoVO)allColumn.stream().filter((cvo) -> c.getColumnName().equals(cvo.getColumnname())).findFirst().get();
            String columnSize = c.getColumnSize();
            if (!"STRING".equals(c.getColumnType().toUpperCase(Locale.ROOT)) && !"BLOB".equals(c.getColumnType().toUpperCase(Locale.ROOT)) && !"CLOB".equals(c.getColumnType().toUpperCase(Locale.ROOT)) && !"JSON".equals(c.getColumnType().toUpperCase(Locale.ROOT))) {
               if (max > 0 && Integer.parseInt(columnSize) >= max) {
                  columnSize = String.valueOf(max);
               } else {
                  String columnSizeTemp = EncUtils.strColumnSize(tCoreDatasystem.getDbtype(), c.getColumnType(), c.getColumnSize(), c.getIsLike(), "0", c.getEncryptionType());
                  if (tCoreDatasystem.getDbtype().equals(EdbType.ORACLE.toString()) && "CHAR".equals(c.getColumnType().toUpperCase(Locale.ROOT)) || tCoreDatasystem.getDbtype().equals(EdbType.KINGBASE.toString()) && "BPCHAR".equals(c.getColumnType().toUpperCase(Locale.ROOT))) {
                     if (Long.parseLong(columnSizeTemp) <= Long.parseLong(c.getRealitycolumnsize())) {
                        continue;
                     }

                     columnSize = columnSizeTemp;
                  } else {
                     columnSize = columnSizeTemp;
                  }
               }

               columnSize = "(" + columnSize + ")";
               String remark = columnInfoVO.getRemarks();
               if (!tCoreDatasystem.getDbtype().equals(EdbType.MYSQL.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.OCEANBASE.toString()) && !EdbType.MARIADB.toString().equals(tCoreDatasystem.getDbtype())) {
                  if (!tCoreDatasystem.getDbtype().equals(EdbType.GREENPLUM.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.POSTGRESQL.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.KINGBASE.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.GAUSS.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.GAUSSDB.toString())) {
                     if (!tCoreDatasystem.getDbtype().equals(EdbType.DM.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.ORACLE.toString())) {
                        if (tCoreDatasystem.getDbtype().equals(EdbType.DB2.toString())) {
                           alterSqlBuilder.append(" alter column \"").append(c.getColumnName()).append("\" ").append(" set data type ").append(c.getColumnType()).append(columnSize);
                        }
                     } else {
                        alterSqlBuilder.append("\"").append(c.getColumnName()).append("\" ").append(c.getColumnType()).append(columnSize).append(",");
                     }
                  } else {
                     alterSqlBuilder.append(" alter column \"").append(c.getColumnName()).append("\" type ").append(c.getColumnType()).append(columnSize).append(",");
                  }
               } else {
                  alterSqlBuilder.append(" modify ").append(c.getColumnName()).append(" ").append(c.getColumnType()).append(columnSize);
                  alterSqlBuilder.append(" comment '").append(remark).append("' ");
                  alterSqlBuilder.append(",");
               }
            }
         }

         if (!"DB2".equals(tCoreDatasystem.getDbtype())) {
            if (alterSqlBuilder.indexOf(",") < 0) {
               return;
            }

            alterSqlBuilder = alterSqlBuilder.deleteCharAt(alterSqlBuilder.length() - 1);
         }

         if (tCoreDatasystem.getDbtype().equals(EdbType.DM.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.ORACLE.toString())) {
            alterSqlBuilder.append(")");
         }

         String alterSql = alterSqlBuilder.toString();
         PreparedStatement preStatement = con.prepareStatement(alterSql);
         preStatement.executeUpdate();
         preStatement.close();
         if ("DB2".equals(tCoreDatasystem.getDbtype())) {
            CallableStatement cs = con.prepareCall("call SYSPROC.ADMIN_CMD('reorg table " + schema + "." + tableName + "')");
            cs.execute();
            cs.close();
         }

         if (null != alterSql) {
            encryptionlogger.info("扩展原列长度完成：  sql语句：" + alterSql);
         }

      }
   }

   public static void backUpCopyColumn(Connection connection, Logger encryptionlogger, com.chenyang.nse.bussiness.entity.vo.strategy.ColumnInfoVO columnInfoVO, TCoreDatasystem tCoreDatasystem, String schema, String tableName, String copySuffix, ColumnInfoVO pkey) throws SQLException {
      if (EdbType.DB2.toString().equals(tCoreDatasystem.getDbtype())) {
         String db2PrimaryKey = pkey.getColumnname();
         String countSql = "select count(1) as table_count from " + schema + "." + tableName;
         Statement statement = connection.createStatement();
         ResultSet res = statement.executeQuery(countSql);

         int var26;
         for(int countInt = 0; res.next(); var26 = res.getInt("table_count")) {
         }

         int step = 1;
         int base = 2000;
         int offset = 0;
         String min = "";
         String max = "";
         String selectMinSql = "select " + db2PrimaryKey + " from " + schema + "." + tableName + " order by " + db2PrimaryKey + " limit 1";

         for(ResultSet selectMinRes = statement.executeQuery(selectMinSql); selectMinRes.next(); min = selectMinRes.getString(db2PrimaryKey)) {
         }

         do {
            max = "";
            offset = step * base;
            String selectSql = "select " + db2PrimaryKey + " from " + schema + "." + tableName + " order by " + db2PrimaryKey + " limit 1 offset " + offset;
            StringBuilder db2Builder = new StringBuilder();
            db2Builder.append(" update \"").append(schema).append("\".\"").append(tableName).append("\" set ");
            db2Builder.append("\"").append(columnInfoVO.getColumnName() + copySuffix).append("\" = \"").append(columnInfoVO.getColumnName()).append("\"");
            if (min == "") {
               statement.execute(db2Builder.toString());
               statement.close();
               break;
            }

            statement = connection.createStatement();

            for(ResultSet selectRes = statement.executeQuery(selectSql); selectRes.next(); max = selectRes.getString(db2PrimaryKey)) {
            }

            db2Builder.append(" where ").append("\"" + db2PrimaryKey + "\"").append(" >= ").append("'" + min + "'");
            if (!max.equals("")) {
               db2Builder.append(" and ").append("\"" + db2PrimaryKey + "\"").append(" <= ").append("'" + max + "'");
            }

            db2Builder.append(" and ").append("\"" + columnInfoVO.getColumnName() + "\"").append(" not like '%" + ENCRYPT_LABEL + "%'");
            statement.execute(db2Builder.toString());
            min = max;
            ++step;
            statement.close();
         } while(!max.equals(""));

      } else {
         StringBuilder backUpSqlBuilder = new StringBuilder();
         if (!EdbType.MYSQL.toString().equals(tCoreDatasystem.getDbtype()) && !EdbType.MSSQLSERVER.toString().equals(tCoreDatasystem.getDbtype()) && !EdbType.HIVE.toString().equals(tCoreDatasystem.getDbtype()) && !EdbType.HIVE_TDH.toString().equals(tCoreDatasystem.getDbtype()) && !EdbType.OCEANBASE.toString().equals(tCoreDatasystem.getDbtype()) && !EdbType.MARIADB.toString().equals(tCoreDatasystem.getDbtype())) {
            if (EdbType.ORACLE.toString().equals(tCoreDatasystem.getDbtype()) || EdbType.POSTGRESQL.toString().equals(tCoreDatasystem.getDbtype()) || EdbType.GREENPLUM.toString().equals(tCoreDatasystem.getDbtype()) || EdbType.DM.toString().equals(tCoreDatasystem.getDbtype()) || EdbType.KINGBASE.toString().equals(tCoreDatasystem.getDbtype()) || EdbType.GAUSS.toString().equals(tCoreDatasystem.getDbtype()) || EdbType.DB2.toString().equals(tCoreDatasystem.getDbtype()) || tCoreDatasystem.getDbtype().equals(EdbType.GAUSSDB.toString())) {
               backUpSqlBuilder.append(" update \"").append(schema).append("\".\"").append(tableName).append("\" set ");
               if ((!EdbType.ORACLE.toString().equals(tCoreDatasystem.getDbtype()) || !columnInfoVO.getColumnType().toLowerCase(Locale.ROOT).contains("char")) && (!EdbType.KINGBASE.toString().equals(tCoreDatasystem.getDbtype()) || !columnInfoVO.getColumnType().toLowerCase(Locale.ROOT).contains("bpchar"))) {
                  backUpSqlBuilder.append("\"").append(columnInfoVO.getColumnName() + copySuffix).append("\" = \"").append(columnInfoVO.getColumnName()).append("\"");
               } else {
                  backUpSqlBuilder.append("\"").append(columnInfoVO.getColumnName() + copySuffix).append("\" = trim(\"").append(columnInfoVO.getColumnName()).append("\")");
               }
            }
         } else {
            backUpSqlBuilder.append(" update ").append(schema).append(".").append(tableName).append(" set ");
            backUpSqlBuilder.append(columnInfoVO.getColumnName() + copySuffix).append(" = ").append(columnInfoVO.getColumnName());
         }

         backUpSqlBuilder.append(" where 1 = 1 ");
         if (!EdbType.MYSQL.toString().equals(tCoreDatasystem.getDbtype()) && !EdbType.MSSQLSERVER.toString().equals(tCoreDatasystem.getDbtype()) && !EdbType.HIVE.toString().equals(tCoreDatasystem.getDbtype()) && !EdbType.HIVE_TDH.toString().equals(tCoreDatasystem.getDbtype()) && !EdbType.OCEANBASE.toString().equals(tCoreDatasystem.getDbtype()) && !EdbType.MARIADB.toString().equals(tCoreDatasystem.getDbtype())) {
            if (EdbType.ORACLE.toString().equals(tCoreDatasystem.getDbtype()) || EdbType.POSTGRESQL.toString().equals(tCoreDatasystem.getDbtype()) || EdbType.GREENPLUM.toString().equals(tCoreDatasystem.getDbtype()) || EdbType.DM.toString().equals(tCoreDatasystem.getDbtype()) || EdbType.KINGBASE.toString().equals(tCoreDatasystem.getDbtype()) || EdbType.GAUSS.toString().equals(tCoreDatasystem.getDbtype()) || tCoreDatasystem.getDbtype().equals(EdbType.GAUSSDB.toString()) || EdbType.DB2.toString().equals(tCoreDatasystem.getDbtype())) {
               backUpSqlBuilder.append(" and \"").append(columnInfoVO.getColumnName()).append("\" not like '%").append(ENCRYPT_LABEL).append("%' ");
            }
         } else if (!"BLOB".equals(columnInfoVO.getColumnType())) {
            backUpSqlBuilder.append(" and ").append(columnInfoVO.getColumnName()).append(" not like '%").append(ENCRYPT_LABEL).append("%' ");
         }

         String backUpSql = backUpSqlBuilder.toString();
         PreparedStatement preStatement = connection.prepareStatement(backUpSql);
         preStatement.executeUpdate();
         preStatement.close();
         if (null != backUpSql) {
            encryptionlogger.info("备份原列数据完成：  sql语句：" + backUpSql);
         }

      }
   }

   public static void addColumnLength(Connection con, Logger encryptionlogger, com.chenyang.nse.bussiness.entity.vo.strategy.ColumnInfoVO columnInfoVO, TCoreDatasystem tCoreDatasystem, String schema, String tableName, List<ColumnInfoVO> allColumnList) throws SQLException {
      if (!"STRING".equals(columnInfoVO.getColumnType().toUpperCase(Locale.ROOT)) && !"CLOB".equals(columnInfoVO.getColumnType().toUpperCase(Locale.ROOT))) {
         int max = 0;

         try {
            Properties properties = PropertiesLoaderUtils.loadAllProperties("config.properties");
            String property = properties.getProperty("encryption.field.max");
            if (property != null && property.length() > 0) {
               max = Integer.valueOf(property.trim());
            }
         } catch (Exception e) {
            e.printStackTrace();
         }

         if (tCoreDatasystem.getDbtype().equals(EdbType.HIVE_TDH.toString())) {
            String sql = "alter table " + schema + "." + tableName + " change " + columnInfoVO.getColumnName() + " " + columnInfoVO.getColumnName() + " " + columnInfoVO.getColumnType();
            String columnSize = columnInfoVO.getColumnSize();
            if (max > 0 && Integer.parseInt(columnSize) >= max) {
               columnSize = String.valueOf(max);
            } else {
               columnSize = EncUtils.strColumnSize(tCoreDatasystem.getDbtype(), columnInfoVO.getColumnType(), columnInfoVO.getColumnSize(), columnInfoVO.getIsLike(), "0", columnInfoVO.getEncryptionType());
            }

            columnSize = "(" + columnSize + ")";
            sql = sql + columnSize;
            PreparedStatement preStatement = con.prepareStatement(sql);
            preStatement.executeUpdate();
            preStatement.close();
            if (null != sql) {
               encryptionlogger.info("扩展原列长度完成：  sql语句：" + sql);
            }

         } else if (tCoreDatasystem.getDbtype().equals(EdbType.MSSQLSERVER.toString())) {
            String sql = "alter table " + schema + "." + tableName + " alter column " + columnInfoVO.getColumnName() + " " + columnInfoVO.getColumnType();
            String columnSize = columnInfoVO.getColumnSize();
            if (max > 0 && Integer.parseInt(columnSize) >= max) {
               columnSize = String.valueOf(max);
            } else {
               columnSize = EncUtils.strColumnSize(tCoreDatasystem.getDbtype(), columnInfoVO.getColumnType(), columnInfoVO.getColumnSize(), columnInfoVO.getIsLike(), "0", columnInfoVO.getEncryptionType());
            }

            columnSize = "(" + columnSize + ")";
            sql = sql + columnSize;
            PreparedStatement preStatement = con.prepareStatement(sql);
            preStatement.executeUpdate();
            preStatement.close();
            con.commit();
            if (null != sql) {
               encryptionlogger.info("扩展原列长度完成：  sql语句：" + sql);
            }

         } else {
            StringBuilder alterSqlBuilder = new StringBuilder();
            if (!tCoreDatasystem.getDbtype().equals(EdbType.MYSQL.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.OCEANBASE.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.DB2.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.MARIADB.toString())) {
               if (!tCoreDatasystem.getDbtype().equals(EdbType.GREENPLUM.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.POSTGRESQL.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.KINGBASE.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.GAUSS.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.GAUSSDB.toString())) {
                  if (tCoreDatasystem.getDbtype().equals(EdbType.DM.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.ORACLE.toString())) {
                     alterSqlBuilder.append("alter table \"").append(schema).append("\".\"").append(tableName).append("\" modify ( ");
                  }
               } else {
                  alterSqlBuilder.append("alter table \"").append(schema).append("\".\"").append(tableName).append("\"");
               }
            } else {
               alterSqlBuilder.append("alter table ").append(schema).append(".").append(tableName);
            }

            String columnSize = columnInfoVO.getColumnSize();
            if (max > 0 && Integer.parseInt(columnSize) >= max) {
               columnSize = String.valueOf(max);
            } else {
               columnSize = EncUtils.strColumnSize(tCoreDatasystem.getDbtype(), columnInfoVO.getColumnType(), columnInfoVO.getColumnSize(), columnInfoVO.getIsLike(), "0", columnInfoVO.getEncryptionType());
            }

            columnSize = "(" + columnSize + ")";
            ColumnInfoVO newcolumnInfoVO = (ColumnInfoVO)allColumnList.stream().filter((cvo) -> columnInfoVO.getColumnName().equals(cvo.getColumnname())).findFirst().get();
            String remark = newcolumnInfoVO.getRemarks();
            if (!tCoreDatasystem.getDbtype().equals(EdbType.MYSQL.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.OCEANBASE.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.MARIADB.toString())) {
               if (tCoreDatasystem.getDbtype().equals(EdbType.GREENPLUM.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.POSTGRESQL.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.KINGBASE.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.GAUSS.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.GAUSSDB.toString())) {
                  alterSqlBuilder.append(" alter column \"").append(columnInfoVO.getColumnName()).append("\" type ").append(columnInfoVO.getColumnType()).append(columnSize);
               }
            } else {
               alterSqlBuilder.append(" modify ").append(columnInfoVO.getColumnName()).append(" ").append(columnInfoVO.getColumnType()).append(columnSize);
               alterSqlBuilder.append(" comment '").append(remark).append("' ");
            }

            if (!tCoreDatasystem.getDbtype().equals(EdbType.DM.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.ORACLE.toString())) {
               if (tCoreDatasystem.getDbtype().equals(EdbType.DB2.toString())) {
                  alterSqlBuilder.append(" alter column \"").append(columnInfoVO.getColumnName()).append("\" ").append(" set data type ").append(columnInfoVO.getColumnType()).append(columnSize);
               }
            } else {
               alterSqlBuilder.append(columnInfoVO.getColumnName()).append(" ").append(columnInfoVO.getColumnType()).append(columnSize);
            }

            if (tCoreDatasystem.getDbtype().equals(EdbType.DM.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.ORACLE.toString())) {
               alterSqlBuilder.append(")");
            }

            String alterSql = alterSqlBuilder.toString();
            PreparedStatement preStatement = con.prepareStatement(alterSql);
            preStatement.executeUpdate();
            preStatement.close();
            if ("DB2".equals(tCoreDatasystem.getDbtype())) {
               CallableStatement cs = con.prepareCall("call SYSPROC.ADMIN_CMD('reorg table " + schema + "." + tableName + "')");
               cs.execute();
               cs.close();
            }

            if (tCoreDatasystem.getDbtype().equals(EdbType.GREENPLUM.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.POSTGRESQL.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.GAUSSDB.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.GAUSS.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.KINGBASE.toString())) {
               con.commit();
            }

            if (null != alterSql) {
               encryptionlogger.info("扩展原列长度完成：  sql语句：" + alterSql);
            }

         }
      }
   }

   public static void rollbackAllColumnLength(Connection con, Logger encryptionlogger, TCoreDatasystem tCoreDatasystem, List<com.chenyang.nse.bussiness.entity.vo.strategy.ColumnInfoVO> columnInfoList, String schema, String tableName) throws SQLException {
      if (tCoreDatasystem.getDbtype().equals(EdbType.HIVE_TDH.toString())) {
         List<String> sqlList = new ArrayList();

         for(com.chenyang.nse.bussiness.entity.vo.strategy.ColumnInfoVO c : columnInfoList) {
            String sql = "alter table " + tableName + "." + schema + " change " + c.getColumnName() + " " + c.getColumnName() + " " + c.getColumnType();
            String columnSize = c.getColumnSize();
            columnSize = "(" + columnSize + ")";
            sql = sql + columnSize;
            sqlList.add(sql);
         }

         for(String s : sqlList) {
            PreparedStatement preStatement = con.prepareStatement(s);
            preStatement.executeUpdate();
            preStatement.close();
            if (null != s) {
               encryptionlogger.info("回滚原列长度完成：  sql语句：" + s);
            }
         }

      } else if (tCoreDatasystem.getDbtype().equals(EdbType.MSSQLSERVER.toString())) {
         List<String> sqlList = new ArrayList();

         for(com.chenyang.nse.bussiness.entity.vo.strategy.ColumnInfoVO c : columnInfoList) {
            String sql = "alter table " + tableName + "." + schema + " alter " + c.getColumnName() + " " + c.getColumnType();
            String columnSize = c.getColumnSize();
            columnSize = "(" + columnSize + ")";
            sql = sql + columnSize;
            sqlList.add(sql);
         }

         for(String s : sqlList) {
            PreparedStatement preStatement = con.prepareStatement(s);
            preStatement.executeUpdate();
            preStatement.close();
            con.commit();
            if (null != s) {
               encryptionlogger.info("回滚原列长度完成：  sql语句：" + s);
            }
         }

      } else {
         StringBuilder alterSqlBuilder = new StringBuilder();
         if (tCoreDatasystem.getDbtype().equals(EdbType.MYSQL.toString())) {
            alterSqlBuilder.append("alter table ").append(schema).append(".").append(tableName);
         } else if (!tCoreDatasystem.getDbtype().equals(EdbType.GREENPLUM.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.POSTGRESQL.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.GAUSSDB.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.KINGBASE.toString()) && !tCoreDatasystem.getDbtype().equals(EdbType.GAUSS.toString())) {
            if (tCoreDatasystem.getDbtype().equals(EdbType.DM.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.ORACLE.toString())) {
               alterSqlBuilder.append("alter table \"").append(schema).append("\".\"").append(tableName).append("\" modify ( ");
            }
         } else {
            alterSqlBuilder.append("alter table \"").append(schema).append("\".\"").append(tableName).append("\"");
         }

         for(com.chenyang.nse.bussiness.entity.vo.strategy.ColumnInfoVO c : columnInfoList) {
            if (!c.getColumnType().equalsIgnoreCase("clob")) {
               String columnSize = c.getColumnSize();
               columnSize = "(" + columnSize + ")";
               if (tCoreDatasystem.getDbtype().equals(EdbType.MYSQL.toString())) {
                  alterSqlBuilder.append(" modify ").append(c.getColumnName()).append(" ").append(c.getColumnType()).append(columnSize).append(",");
               } else if (tCoreDatasystem.getDbtype().equals(EdbType.GREENPLUM.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.POSTGRESQL.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.GAUSSDB.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.KINGBASE.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.GAUSS.toString())) {
                  alterSqlBuilder.append(" alter column \"").append(c.getColumnName()).append("\" type ").append(c.getColumnType()).append(columnSize).append(",");
               }

               if (tCoreDatasystem.getDbtype().equals(EdbType.DM.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.ORACLE.toString())) {
                  alterSqlBuilder.append(c.getColumnName()).append(" ").append(c.getColumnType()).append(columnSize).append(",");
               }
            }
         }

         alterSqlBuilder = alterSqlBuilder.deleteCharAt(alterSqlBuilder.length() - 1);
         if (tCoreDatasystem.getDbtype().equals(EdbType.DM.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.ORACLE.toString())) {
            alterSqlBuilder.append(")");
         }

         String alterSql = alterSqlBuilder.toString();
         PreparedStatement preStatement = con.prepareStatement(alterSql);
         preStatement.executeUpdate();
         preStatement.close();
         if (tCoreDatasystem.getDbtype().equals(EdbType.GREENPLUM.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.POSTGRESQL.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.GAUSSDB.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.GAUSS.toString()) || tCoreDatasystem.getDbtype().equals(EdbType.KINGBASE.toString())) {
            con.commit();
         }

         if (null != alterSql) {
            encryptionlogger.info("回滚原列长度完成：  sql语句：" + alterSql);
         }

      }
   }

   public static void backUpOneCopyColumnMongoDB(MongoClient connect, String schema, String table, com.chenyang.nse.bussiness.entity.vo.strategy.ColumnInfoVO columnInfo, String copySuffix) {
      MongoDatabase db = connect.getDatabase(schema);
      MongoCollection<Document> collection = db.getCollection(table);
      String pattern = "^(?!.*" + ENCRYPT_LABEL + ").*$";
      Bson regex = Filters.regex(columnInfo.getColumnName(), pattern);
      Bson sort = Filters.eq(MONGODBPK, 1);
      int count = 0;
      int max = 100000;

      while(true) {
         FindIterable<Document> find = collection.find(regex).sort(sort).skip(count).limit(max);
         MongoCursor<Document> cursor = find.iterator();
         List<Document> results = new ArrayList();

         while(cursor.hasNext()) {
            results.add(cursor.next());
         }

         if (results.size() == 0) {
            return;
         }

         for(Document document : results) {
            String value = MongodbTool.getDocumentValue(columnInfo.getColumnName(), document);
            Object pk = document.get(MONGODBPK);
            Bson eq = Filters.eq(MONGODBPK, pk);
            collection.updateMany(eq, new Document("$set", new Document(columnInfo.getColumnName() + copySuffix, value)));
         }

         count += max;
      }
   }

   static {
      try {
         properties = PropertiesLoaderUtils.loadAllProperties("config.properties");
         ENCRYPT_LABEL = properties.get("encryption.label").toString();
         MONGODBPK = properties.getProperty("encryption.mongodbpk");
      } catch (IOException e) {
         e.printStackTrace();
      }

   }
}
