package com.chenyang.nse.bussiness.service.core.impl;

import com.chenyang.nse.bussiness.config.PropertiesLoaderUtils;
import com.chenyang.nse.bussiness.dao.table.console.TConsoleDictionaryDao;
import com.chenyang.nse.bussiness.dao.table.core.TCoreConfigDao;
import com.chenyang.nse.bussiness.dao.table.core.TCoreCurrencyInfoDao;
import com.chenyang.nse.bussiness.dao.table.core.TCoreDatasystemDao;
import com.chenyang.nse.bussiness.entity.db.ColumnInfo;
import com.chenyang.nse.bussiness.entity.orm.table.core.TCoreConfig;
import com.chenyang.nse.bussiness.entity.orm.table.core.TCoreCurrencyInfo;
import com.chenyang.nse.bussiness.entity.orm.table.core.TCoreDatasystem;
import com.chenyang.nse.bussiness.entity.vo.ProgressInfo;
import com.chenyang.nse.bussiness.entity.vo.SensitiveColumn;
import com.chenyang.nse.bussiness.enumeration.EdbType;
import com.chenyang.nse.bussiness.service.core.CurrencyService;
import com.chenyang.nse.bussiness.service.core.DataSystemService;
import com.chenyang.nse.bussiness.tools.jdbc.JdbcTool;
import com.chenyang.nse.bussiness.tools.xml.XmlTool;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Pattern;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class CurrencyServiceImpl implements CurrencyService {
   @Autowired
   private TCoreDatasystemDao tCoreDatasystemDao;
   @Autowired
   private TCoreCurrencyInfoDao tCoreCurrencyInfoDao;
   @Autowired
   private TConsoleDictionaryDao tConsoleDictionaryDao;
   @Autowired
   private DataSystemService dataSystemService;
   @Autowired
   private TCoreConfigDao tCoreConfigDao;
   public static final String CURRENCY_TYPECODE = "18";

   public void getAllSchemaCurrencyInfo(String samplingtype, TCoreDatasystem datasystem, String datasystemid, List<String> schemas, long maxRowCount, ProgressInfo progressInfo) {
      new Properties();

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

      List<String> timeLogList = new ArrayList();
      timeLogList.add("敏感字段查询开始：" + System.currentTimeMillis());
      new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      new ArrayList();
      new ArrayList();
      String dbType = datasystem.getDbtype();
      this.iskeberos(datasystem);
      Connection connection = JdbcTool.getConnection(datasystem);
      long schemaIndex = 1L;
      progressInfo.setSchemaCount((long)schemas.size());
      HashMap<String, List<String>> hash = new HashMap();
      List<String> schemaslist = new ArrayList();

      for(String schema : schemas) {
         List<String> table = new ArrayList();
         String[] s = schema.split("~");
         String a = s[0];
         String b = s[1];
         if (hash.get(a) == null) {
            table.add(b);
            hash.put(a, table);
            schemaslist.add(a);
         } else {
            table = (List)hash.get(a);
            table.add(b);
            hash.put(a, table);
         }
      }

      Iterator var32 = schemaslist.iterator();

      while(true) {
         while(true) {
            if (!var32.hasNext()) {
               try {
                  connection.close();
               } catch (Exception e) {
                  e.printStackTrace();
               }

               return;
            }

            String schema = (String)var32.next();
            String tableInfo = null;
            progressInfo.setCurrentState("notReady");
            progressInfo.setCurrentSchema(schemaIndex);
            progressInfo.setCurrentSchemaName(schema);
            List<String> allTableListOfSchema = new ArrayList();
            new TCoreCurrencyInfo();
            List<TCoreCurrencyInfo> tableInfoL = this.tCoreCurrencyInfoDao.getCurrencyInfoTable(datasystem.getSysname(), schema);
            if (tableInfoL.size() > 0) {
               tableInfo = ((TCoreCurrencyInfo)tableInfoL.get(0)).getCurrencytable();
            }

            if (tableInfo != null && !"".equals(tableInfo)) {
               allTableListOfSchema.add(tableInfo);
               TCoreCurrencyInfo var38 = this.isCur(allTableListOfSchema, dbType, schema, connection, progressInfo, timeLogList, datasystem);
               if (var38.getCurrencytable() != null) {
                  break;
               }

               this.tCoreCurrencyInfoDao.remove(new Criterion[]{Restrictions.eq("datasystemid", datasystem.getSysname()), Restrictions.eq("schemaer", schema), Restrictions.eq("currencytable", tableInfo)});
               allTableListOfSchema.clear();
               Connection conn = this.dataSystemService.getConnectionByDataSystemId(datasystemid);
               if (conn != null) {
                  List<String> tablelist = JdbcTool.getAllTableName(conn, schema);
                  JdbcTool.closeConnection(conn);

                  for(String str : tablelist) {
                     allTableListOfSchema.add(str);
                  }
               }

               var38 = this.isCur(allTableListOfSchema, dbType, schema, connection, progressInfo, timeLogList, datasystem);
               if (var38.getCurrencytable() != null) {
                  this.tCoreCurrencyInfoDao.save(var38);
                  break;
               }
            } else {
               Connection conn = this.dataSystemService.getConnectionByDataSystemId(datasystemid);
               new ArrayList();
               if (conn != null) {
                  List<String> tablelist = JdbcTool.getAllTableName(conn, schema);
                  JdbcTool.closeConnection(conn);

                  for(String str : tablelist) {
                     allTableListOfSchema.add(str);
                  }
               }

               TCoreCurrencyInfo var37 = this.isCur(allTableListOfSchema, dbType, schema, connection, progressInfo, timeLogList, datasystem);
               if (var37.getCurrencytable() != null) {
                  this.tCoreCurrencyInfoDao.save(var37);
                  break;
               }
            }
         }

         ++schemaIndex;
      }
   }

   private TCoreCurrencyInfo isCur(List<String> allTableListOfSchema, String dbType, String schema, Connection connection, ProgressInfo progressInfo, List<String> timeLogList, TCoreDatasystem datasystem) {
      int queryTableDataErrorCount = 0;
      int queryTableDataAgainErrorCount = 0;
      int otherErrorCount = 0;
      TCoreCurrencyInfo nowIsCurrencyInfo = new TCoreCurrencyInfo();
      String queryTableDataSql = this.getQuerySql(dbType, schema);
      List<Pattern> patternList = new ArrayList();

      try {
         List<String> currdic = this.tConsoleDictionaryDao.queryValueByTypeCode("18");

         for(String tableName : allTableListOfSchema) {
            String queryTableDataSqlTemp = "";
            TCoreConfig tcoreConfig = (TCoreConfig)this.tCoreConfigDao.queryUnique(new Criterion[]{Restrictions.eq("datasystemid", datasystem.getId())});
            if (tcoreConfig != null) {
               String columnSurroundCharacterLeft = tcoreConfig.getColumnSurroundCharacterLeft();
               String columnSurroundCharacterRight = tcoreConfig.getColumnSurroundCharacterRight();
               if (columnSurroundCharacterLeft == null || columnSurroundCharacterLeft.equals("") || columnSurroundCharacterRight == null || columnSurroundCharacterRight.equals("")) {
                  columnSurroundCharacterLeft = XmlTool.getFileValue(dbType + "/db-columnSurroundCharacterLeft");
                  columnSurroundCharacterRight = XmlTool.getFileValue(dbType + "/db-columnSurroundCharacterRight");
               }

               List<ColumnInfo> columnamelist = JdbcTool.getAllColumnInfo(connection, schema, tableName);
               String columnameliststr = "";
               StringBuffer sb = new StringBuffer();

               for(int i = 0; i < columnamelist.size(); ++i) {
                  ColumnInfo temp = (ColumnInfo)columnamelist.get(i);
                  if (temp.getTypename().equalsIgnoreCase("sql_variant")) {
                     sb.append("convert(varchar(100), SERVERPROPERTY('" + temp.getColumnname() + "')) as " + columnSurroundCharacterLeft + temp.getColumnname() + columnSurroundCharacterRight);
                  } else {
                     sb.append(columnSurroundCharacterLeft + temp.getColumnname() + columnSurroundCharacterRight);
                  }

                  sb.append(",");
               }

               columnameliststr = sb.toString();
               if (columnameliststr.length() > 0) {
                  columnameliststr = sb.toString().substring(0, sb.toString().length() - 1);
               }

               if (columnameliststr.equals("1")) {
                  queryTableDataSql = this.getQuerySql(dbType, schema);
               }

               queryTableDataSqlTemp = MessageFormat.format(queryTableDataSql, tableName, columnameliststr);
               PreparedStatement tableDataStatement = null;
               ResultSet tableDataResultSet = null;

               try {
                  tableDataStatement = connection.prepareStatement(queryTableDataSqlTemp);
                  progressInfo.setCurrentState("查询表数据");
                  timeLogList.add(tableName);
                  timeLogList.add("查询表数据开始：" + System.currentTimeMillis());
                  tableDataResultSet = tableDataStatement.executeQuery();
                  timeLogList.add("查询表数据结束：" + System.currentTimeMillis());
               } catch (Exception var32) {
                  ++queryTableDataErrorCount;
                  Connection oldConnection = connection;
                  connection = JdbcTool.getConnection(datasystem);

                  try {
                     oldConnection.close();
                  } catch (Exception var31) {
                  }

                  try {
                     tableDataStatement.close();
                  } catch (Exception var30) {
                  }
               }

               if (tableDataResultSet != null) {
                  boolean isCT = this.isCurrencyInfoTable(datasystem.getId(), datasystem.getSysname(), schema, tableDataResultSet, tableName, patternList, progressInfo, timeLogList, currdic);
                  if (isCT) {
                     nowIsCurrencyInfo.setDatasystemid(datasystem.getSysname());
                     nowIsCurrencyInfo.setCurrencytable(tableName);
                     nowIsCurrencyInfo.setSchemaer(schema);
                     break;
                  }
               }

               try {
                  tableDataStatement.close();
               } catch (Exception var29) {
               }
            }
         }
      } catch (Exception e) {
         e.printStackTrace();
      }

      return nowIsCurrencyInfo;
   }

   private String getQuerySql(String dbType, String schema) {
      String sql = null;
      if (EdbType.ORACLE.toString().equals(dbType)) {
         sql = "select {1} from " + schema + ".\"{0}\" where rownum <= 1000";
      } else if (EdbType.DB2.toString().equals(dbType)) {
         sql = "select {1} from " + schema + ".\"{0}\" FETCH FIRST 1000 ROWS ONLY";
      } else if (EdbType.INFORMIX.toString().equals(dbType)) {
         sql = "select first 1000 {1} from " + schema + ".{0} ";
      } else if (!EdbType.MYSQL.toString().equals(dbType) && !EdbType.MARIADB.toString().equals(dbType)) {
         if (EdbType.MSSQLSERVER.toString().equals(dbType)) {
            sql = "select top 1000 {1} from  " + schema + ".\"{0}\"";
         } else if (EdbType.HIVE.toString().equals(dbType)) {
            sql = "select {1} from " + schema + ".{0} order by rand() limit 1000";
         } else if (EdbType.SYBASE.toString().equals(dbType)) {
            sql = " SET ROWCOUNT 1000 SELECT {1} FROM " + schema + ".\"{0}\" SET ROWCOUNT 0";
         } else if (EdbType.AS400.toString().equals(dbType)) {
            sql = "select {1} from " + schema + ".\"{0}\" FETCH FIRST 1000 ROWS ONLY";
         } else if (EdbType.SYBASE_IQ.toString().equals(dbType)) {
            sql = " SET ROWCOUNT 1000 SELECT {1} FROM " + schema + ".\"{0}\" SET ROWCOUNT 0";
         } else if (EdbType.TERADATA.toString().equals(dbType)) {
            sql = " SELECT top 1000 {1} FROM " + schema + ".\"{0}\" ;";
         } else if (EdbType.GREENPLUM.toString().equals(dbType)) {
            sql = "select {1} from " + schema + ".{0}  limit  1000";
         } else if (EdbType.HANA.toString().equals(dbType)) {
            sql = "select {1} from " + schema + ".{0}  limit 1000";
         }
      } else {
         sql = "select {1} from  " + schema + ".{0} limit 1000";
      }

      return sql;
   }

   public boolean isCurrencyInfoTable(String datasourceid, String datasourcename, String schema, ResultSet resultSet, String tableName, List<Pattern> patternList, ProgressInfo progressInfo, List<String> timeLogList, List<String> currdic) {
      List<SensitiveColumn> sensitiveColumns = new ArrayList();
      Properties props = new Properties();

      try {
         props = PropertiesLoaderUtils.loadAllProperties("config.properties");
      } catch (Exception var49) {
      }

      boolean ischarsetflag = false;
      String ischarset_s = "";
      String ischarset_t = "";
      if (datasourceid != null) {
         TCoreDatasystem tCoreDatasystem = (TCoreDatasystem)this.tCoreDatasystemDao.get(datasourceid);
         if (tCoreDatasystem != null) {
            String ischarset = tCoreDatasystem.getIscharset();
            if (ischarset != null && !"".equals(ischarset) && ischarset.split(",").length == 2) {
               ischarsetflag = true;
               ischarset_s = ischarset.split(",")[0];
               ischarset_t = ischarset.split(",")[1];
            }
         }
      }

      String isrepeatvalue = props.get("isrepeatvalue").toString();

      boolean i;
      try {
         Map<Integer, List<String>> columnValueMap = new HashMap();
         Map<Integer, Set<String>> columnDistinctValueMap = new HashMap();
         ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
         int columnCount = resultSetMetaData.getColumnCount();
         long rowCount = 0L;
         long[] nullOrEmptyCount = new long[columnCount];
         progressInfo.setCurrentState("提取数据");
         timeLogList.add("提取表数据开始：" + System.currentTimeMillis());
         if (columnCount <= 5) {
            while(resultSet.next()) {
               for(int inew = 0; inew < columnCount; ++inew) {
                  if (rowCount == 0L) {
                     columnValueMap.put(inew, new ArrayList());
                     columnDistinctValueMap.put(inew, new HashSet());
                  }

                  Object columnValueObj = null;
                  if (resultSetMetaData.getColumnType(inew + 1) == 2009) {
                     System.out.println("表名：" + tableName);
                     System.out.println("不支持的列：" + resultSetMetaData.getColumnName(inew + 1));
                  } else {
                     try {
                        columnValueObj = resultSet.getObject(inew + 1);
                     } catch (Exception var48) {
                        columnValueObj = null;
                     }
                  }

                  if (columnValueObj != null) {
                     String columnValue = columnValueObj.toString();
                     if (columnValueObj instanceof byte[]) {
                        columnValue = "";
                     }

                     if (ischarsetflag) {
                        columnValue = new String(columnValue.getBytes(ischarset_s), ischarset_t);
                        System.out.println(columnValue);
                     }

                     if (!"".equals(columnValue.trim())) {
                        ((List)columnValueMap.get(inew)).add(columnValue);
                        ((Set)columnDistinctValueMap.get(inew)).add(columnValue);
                     } else {
                        int var10002 = (int) nullOrEmptyCount[inew]++;
                     }
                  } else {
                     int var60 = (int) nullOrEmptyCount[inew]++;
                  }
               }

               ++rowCount;
            }

            timeLogList.add("提取表数据结束：" + System.currentTimeMillis());
            if (rowCount != 0L) {
               timeLogList.add("匹配表数据开始：" + System.currentTimeMillis());

               for(int inew = 0; inew < columnCount; ++inew) {
                  String columnname = resultSetMetaData.getColumnName(inew + 1);
                  long validCount = rowCount - nullOrEmptyCount[inew];
                  double distinctCount = (double)((Set)columnDistinctValueMap.get(inew)).size();
                  SensitiveColumn column = new SensitiveColumn(datasourceid, datasourcename, schema, tableName, columnname, rowCount, validCount, (long)distinctCount);
                  sensitiveColumns.add(column);
                  List<String> columnValues = (List)columnValueMap.get(inew);
                  if (null != columnValues && columnValues.size() != 0) {
                     long matchCount = 0L;

                     for(String val : columnValues) {
                        if (currdic.contains(val)) {
                           ++matchCount;
                        }
                     }

                     if (matchCount - (long)columnValues.size() == 0L) {
                        timeLogList.add("匹配表数据结束：" + System.currentTimeMillis());
                        boolean var59 = true;
                        return var59;
                     }
                  }
               }

               timeLogList.add("匹配表数据结束：" + System.currentTimeMillis());
               return false;
            }

            i = false;
            return i;
         }

         i = false;
      } catch (Exception e) {
         e.printStackTrace();
         return false;
      } finally {
         try {
            resultSet.close();
         } catch (Exception var47) {
         }

      }

      return i;
   }

   public void iskeberos(TCoreDatasystem datasystem) {
      if ("HIVE".equals(datasystem.getDbtype()) && "on".equals(datasystem.getIskerberos())) {
         System.setProperty("java.security.krb5.conf", datasystem.getXmlpath() + "/krb5.conf");
      }

   }
}
