package util;

import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import util.log.SQLLogger;
import util.sqlparse.DB2Parse;
import util.sqlparse.DmParse;
import util.sqlparse.ElasticSearchParse;
import util.sqlparse.GaussParse;
import util.sqlparse.GreenPlumParse;
import util.sqlparse.HiveParse;
import util.sqlparse.HiveTDHParse;
import util.sqlparse.KingBaseParse;
import util.sqlparse.MariadbParse;
import util.sqlparse.MongoParse;
import util.sqlparse.MySqlParse;
import util.sqlparse.OracleParse;
import util.sqlparse.PostgreSqlParse;
import util.sqlparse.SparkSQLParse;
import util.sqlparse.SqlServerParse;
import util.sqlparse.visitor.common.scope.ReplaceInfo;
import util.sqlparse.visitor.common.scope.Scope;
import util.sqlparse.visitor.postgresql.visitor.ReplaceVisitor;

public class SqlUtil {
   private static List<String> analysisSqlList = new ArrayList();

   public static List<String> getAnalysisSqlList() {
      return analysisSqlList;
   }

   public static void setAnalysisSqlList(List<String> analysisSqlList) {
      SqlUtil.analysisSqlList = analysisSqlList;
   }

   public String parseSql(Map<String, String> param) throws Exception {
      SQLLogger.log((String)param.get("sql"));

      try {
         String dbType = (String)param.get("dbType");
         String parseSql = "";
         if (!"mysql".equals(dbType) && !"KUNDB".equals(dbType)) {
            if ("mariadb".equals(dbType)) {
               MariadbParse mariadbParse = new MariadbParse(param);
               parseSql = mariadbParse.parseSql();
            } else if ("oracle".equals(dbType)) {
               OracleParse oracleParse = new OracleParse(param);
               parseSql = oracleParse.parseSql();
            } else if ("postgresql".equals(dbType)) {
               PostgreSqlParse postgreSqlParse = new PostgreSqlParse(param);
               parseSql = postgreSqlParse.parseSql();
            } else if ("hive".equals(dbType)) {
               HiveParse hiveParse = new HiveParse(param);
               parseSql = hiveParse.parseSql();
            }
         } else {
            MySqlParse mySqlParse = new MySqlParse(param);
            parseSql = mySqlParse.parseSql();
         }

         return parseSql;
      } catch (Exception e) {
         SQLLogger.log((String)param.get("sql"), e.toString());
         throw e;
      }
   }

   public Map<String, Object> parseSqlStructure(Map<String, String> param) {
      SQLLogger.log((String)param.get("sql"));
      String flag = "";
      String sqlparseCache = (String)param.get("sqlparseCache");
      if ("true".equalsIgnoreCase(sqlparseCache)) {
         ParseCacheUtil.isOpen = true;
         flag = ParseCacheUtil.getFlag(param);
         Map<String, Object> cache = (Map)ParseCacheUtil.sqlparseCacheMap.get(flag);
         if (cache != null) {
            return cache;
         }
      }

      Map<String, Object> result = new HashMap();

      try {
         String dbType = (String)param.get("dbType");
         String sql = (String)param.get("sql");
         if (!dbType.equalsIgnoreCase("es") && (sql == null || "".equals(sql))) {
            return result;
         }

         Map<String, Object> stringObjectMap = stringMapToObjectMap(param);
         if ("oracle".equals(dbType)) {
            OracleParse oracleParse = new OracleParse(param);
            oracleParse.parseSqlStructure(result);
         } else if (!"sql server".equals(dbType) && !"sqlserver".equals(dbType)) {
            if ("greenplum".equals(dbType)) {
               GreenPlumParse greenPlumParse = new GreenPlumParse(param);
               greenPlumParse.parseSqlStructure(result);
            } else if ("postgresql".equals(dbType)) {
               PostgreSqlParse postgreSqlParse = new PostgreSqlParse(param);
               postgreSqlParse.parseSqlStructure(result);
            } else if ("dm".equals(dbType)) {
               DmParse dmParse = new DmParse(param);
               dmParse.parseSqlStructure(result);
            } else if ("db2".equals(dbType)) {
               DB2Parse db2Parse = new DB2Parse(param);
               db2Parse.parseSqlStructure(result);
            } else if (!"mysql".equals(dbType) && !"KUNDB".equals(dbType)) {
               if ("mariadb".equals(dbType)) {
                  MariadbParse mariadbParse = new MariadbParse(param);
                  mariadbParse.parseSqlStructure(result);
               } else if ("kingbase".equals(dbType)) {
                  KingBaseParse kingBaseParse = new KingBaseParse(param);
                  kingBaseParse.parseSqlStructure(result);
               } else if ("gauss".equals(dbType)) {
                  GaussParse gaussParse = new GaussParse(param);
                  gaussParse.parseSqlStructure(result);
               } else if ("hive".equals(dbType)) {
                  HiveParse hiveParse = new HiveParse(param);
                  hiveParse.parseSqlStructure(result);
               } else if ("hive_tdh".equals(dbType)) {
                  HiveTDHParse hiveTDHParse = new HiveTDHParse(stringObjectMap);
                  hiveTDHParse.parseSqlStructure(result);
               } else if ("es".equals(dbType)) {
                  ElasticSearchParse esParse = new ElasticSearchParse(param);
                  esParse.parseSqlStructure(result);
               } else if ("sparksql".equals(dbType)) {
                  SparkSQLParse sparkSQLParse = new SparkSQLParse(param);
                  sparkSQLParse.parseSqlStructure(result);
               } else if ("mongodb".equals(dbType)) {
                  MongoParse mongoParse = new MongoParse(param);
                  mongoParse.parseSqlStructure(result);
               }
            } else {
               MySqlParse mySqlParse = new MySqlParse(param);
               mySqlParse.parseSqlStructure(result);
            }
         } else {
            SqlServerParse sqlServerParse = new SqlServerParse(param);
            sqlServerParse.parseSqlStructure(result);
         }

         mapUnionObject2String(stringObjectMap, param);
      } catch (Exception e) {
         SQLLogger.log((String)param.get("sql"), e.toString());
         e.printStackTrace();
      }

      if (ParseCacheUtil.isOpen) {
         ParseCacheUtil.checkLimit();
         ParseCacheUtil.sqlparseCacheMap.put(flag, result);
         System.out.println("not hit cache-------------------------");
      }

      return result;
   }

   public List<Map<String, Object>> parseSqlStructureEnc(Map<String, String> param) {
      List<Map<String, Object>> returnResult = new ArrayList();
      String sqlAll = (String)param.get("sql");
      String[] split = sqlAll.split(";");

      for(String sql : split) {
         sql = sql.trim();
         param.put("sql", sql);
         Map<String, Object> stringObjectMap = this.parseSqlStructure(param);
         returnResult.add(stringObjectMap);
      }

      return returnResult;
   }

   public Map<String, Object> parseSqlStructureAnd(Map<String, String> param) throws Exception {
      try {
         SQLLogger.log((String)param.get("sql"));
         Map<String, Object> result = this.parseSqlStructure(param);
         return result;
      } catch (Exception e) {
         SQLLogger.log((String)param.get("sql"), e.toString());
         throw e;
      }
   }

   public String pareSqlReplaceValue(Map<String, String> param, List<Map> repalceMap) throws Exception {
      SQLLogger.log((String)param.get("sql"));

      try {
         Map<String, Object> result = new HashMap();
         String sql = "";

         try {
            String dbType = (String)param.get("dbType");
            if (!"mysql".equals(dbType) && !"KUNDB".equals(dbType)) {
               if ("mysql".equals(dbType)) {
                  OracleParse oracleParse = new OracleParse(param);
                  oracleParse.parseSqlStructureAndReplace(result, repalceMap);
               } else if ("dm".equals(dbType)) {
                  DmParse dmSqlParse = new DmParse(param);
                  dmSqlParse.parseSqlStructureAndReplace(result, this.ListMapConvertMapString(repalceMap));
               }
            } else {
               MySqlParse mySqlParse = new MySqlParse(param);
               mySqlParse.parseSqlStructureAndReplace(result, this.ListMapConvertMapString(repalceMap));
            }

            sql = (String)result.get("sql");
         } catch (Exception e) {
            e.printStackTrace();
         }

         return sql;
      } catch (Exception e) {
         SQLLogger.log((String)param.get("sql"), e.toString());
         throw e;
      }
   }

   public Map<String, String> ListMapConvertMapString(List<Map> list) {
      Map<String, String> result = new HashMap();

      for(Map<String, String> map : list) {
         for(Map.Entry<String, String> entry : map.entrySet()) {
            String key = (String)entry.getKey();
            String value = (String)entry.getValue();
            result.put(key, value);
         }
      }

      return result;
   }

   public String pareSqlReplaceValue2(Map<String, String> param, List<Map> repalceMap) throws Exception {
      SQLLogger.log((String)param.get("sql"));

      try {
         Map<String, Object> result = new HashMap();
         String sql = (String)param.get("sql");

         try {
            String dbType = (String)param.get("dbType");
            if ("oracle".equals(dbType)) {
               OracleParse oracleParse = new OracleParse(param);
               oracleParse.parseSqlStructureAndReplace2(result, repalceMap);
            } else if (!"sql server".equals(dbType) && !"sqlserver".equals(dbType)) {
               if ("greenplum".equals(dbType)) {
                  GreenPlumParse greenPlumParse = new GreenPlumParse(param);
                  greenPlumParse.parseSqlStructureAndReplace2(result, repalceMap);
               } else if ("postgresql".equals(dbType)) {
                  PostgreSqlParse postgreSqlParse = new PostgreSqlParse(param);
                  postgreSqlParse.parseSqlStructureAndReplace2(result, repalceMap);
               } else if ("dm".equals(dbType)) {
                  DmParse dmSqlParse = new DmParse(param);
                  dmSqlParse.parseSqlStructureAndReplace2(result, repalceMap);
               } else if ("db2".equals(dbType)) {
                  DB2Parse db2SqlParse = new DB2Parse(param);
                  db2SqlParse.parseSqlStructureAndReplace2(result, repalceMap);
               } else if (!"mysql".equals(dbType) && !"KUNDB".equals(dbType)) {
                  if ("mariadb".equals(dbType)) {
                     MariadbParse mariadbParse = new MariadbParse(param);
                     mariadbParse.parseSqlStructureAndReplace2(result, repalceMap);
                  } else if ("kingbase".equals(dbType)) {
                     KingBaseParse kingBaseParse = new KingBaseParse(param);
                     kingBaseParse.parseSqlStructureAndReplace2(result, repalceMap);
                  } else if ("hive".equals(dbType)) {
                     HiveParse hiveParse = new HiveParse(param);
                     hiveParse.parseSqlStructureAndReplace2(result, repalceMap);
                  } else if ("gauss".equals(dbType)) {
                     GaussParse gaussParse = new GaussParse(param);
                     gaussParse.parseSqlStructureAndReplace2(result, repalceMap);
                  } else if ("mongodb".equalsIgnoreCase(dbType)) {
                     MongoParse mongoParse = new MongoParse(param);
                     mongoParse.parseSqlStructureAndReplace(result, repalceMap, true);
                  }
               } else {
                  MySqlParse mySqlParse = new MySqlParse(param);
                  mySqlParse.parseSqlStructureAndReplace2(result, repalceMap);
               }
            } else {
               SqlServerParse sqlServerParse = new SqlServerParse(param);
               sqlServerParse.parseSqlStructureAndReplace2(result, repalceMap);
            }

            sql = (String)result.get("sql");
         } catch (Exception e) {
            e.printStackTrace();
         }

         return sql;
      } catch (Exception e) {
         SQLLogger.log((String)param.get("sql"), e.toString());
         throw e;
      }
   }

   public String column_desensitization(Map<String, Object> paramObject) throws Exception {
      SQLLogger.log((String)paramObject.get("sql"));

      try {
         String dbType = (String)paramObject.get("dbType");
         String parseSql = "";
         Map<String, String> param = objectMapToStringMap(paramObject);
         if ("oracle".equals(dbType)) {
            OracleParse oracleParse = new OracleParse(param);
            parseSql = oracleParse.parseSql_column();
         } else if (!"sql server".equals(dbType) && !"sqlserver".equals(dbType)) {
            if ("greenplum".equals(dbType)) {
               GreenPlumParse greenPlumParse = new GreenPlumParse(param);
               parseSql = greenPlumParse.parseSql_column();
            } else if ("postgresql".equals(dbType)) {
               PostgreSqlParse postgreSqlParse = new PostgreSqlParse(param);
               parseSql = postgreSqlParse.parseSql_column();
            } else if ("dm".equals(dbType)) {
               DmParse dmParse = new DmParse(param);
               parseSql = dmParse.parseSql_column();
            } else if ("db2".equals(dbType)) {
               DB2Parse db2Parse = new DB2Parse(param);
               parseSql = db2Parse.parseSql_column();
            } else if (!"mysql".equals(dbType) && !"KUNDB".equals(dbType)) {
               if ("kingbase".equals(dbType)) {
                  KingBaseParse kingBaseParse = new KingBaseParse(param);
                  parseSql = kingBaseParse.parseSql_column();
               } else if ("mariadb".equals(dbType)) {
                  MariadbParse mariadbParse = new MariadbParse(param);
                  parseSql = mariadbParse.parseSql_column();
               } else if ("hive".equals(dbType)) {
                  HiveParse hiveParse = new HiveParse(param);
                  parseSql = hiveParse.parseSql_column();
               } else if ("gauss".equals(dbType)) {
                  GaussParse gaussParse = new GaussParse(param);
                  parseSql = gaussParse.parseSql_column();
               } else if ("hive_tdh".equals(dbType)) {
                  HiveTDHParse hiveTDHParse = new HiveTDHParse(paramObject);
                  parseSql = hiveTDHParse.parseSql_column();
               } else if ("es".equals(dbType)) {
                  ElasticSearchParse esParse = new ElasticSearchParse(param);
                  parseSql = esParse.parseSql_column();
               } else if ("sparksql".equals(dbType)) {
                  SparkSQLParse sparkSQLParse = new SparkSQLParse(param);
                  parseSql = sparkSQLParse.parseSql_column();
               } else if ("mongodb".equals(dbType)) {
                  MongoParse mongoParse = new MongoParse(param);
                  parseSql = mongoParse.parseSql_column();
               }
            } else {
               MySqlParse mySqlParse = new MySqlParse(param);
               parseSql = mySqlParse.parseSql_column();
            }
         } else {
            SqlServerParse sqlServerParse = new SqlServerParse(param);
            parseSql = sqlServerParse.parseSql_column();
         }

         mapUnionString2Object(param, paramObject);
         return "mongodb".equalsIgnoreCase(dbType) ? parseSql : parseSql.replaceAll("\n", " ");
      } catch (Exception e) {
         SQLLogger.log((String)paramObject.get("sql"), e.toString());
         throw e;
      }
   }

   public String table_desensitization(Map<String, String> param) throws Exception {
      SQLLogger.log((String)param.get("sql"));

      try {
         String dbType = (String)param.get("dbType");
         String parseSql = "";
         Map<String, Object> stringObjectMap = stringMapToObjectMap(param);
         if ("oracle".equals(dbType)) {
            OracleParse oracleParse = new OracleParse(param);
            parseSql = oracleParse.parseSql_table();
         } else if (!"sql server".equals(dbType) && !"sqlserver".equals(dbType)) {
            if ("greenplum".equals(dbType)) {
               GreenPlumParse greenPlumParse = new GreenPlumParse(param);
               parseSql = greenPlumParse.parseSql_table();
            } else if ("postgresql".equals(dbType)) {
               PostgreSqlParse postgreSqlParse = new PostgreSqlParse(param);
               parseSql = postgreSqlParse.parseSql_table();
            } else if ("dm".equals(dbType)) {
               DmParse dmParse = new DmParse(param);
               parseSql = dmParse.parseSql_table();
            } else if ("db2".equals(dbType)) {
               DB2Parse db2Parse = new DB2Parse(param);
               parseSql = db2Parse.parseSql_table();
            } else if (!"mysql".equals(dbType) && !"KUNDB".equals(dbType)) {
               if ("kingbase".equals(dbType)) {
                  KingBaseParse kingBaseParse = new KingBaseParse(param);
                  parseSql = kingBaseParse.parseSql_table();
               } else if ("mariadb".equals(dbType)) {
                  MariadbParse mariadbParse = new MariadbParse(param);
                  parseSql = mariadbParse.parseSql_table();
               } else if ("hive".equals(dbType)) {
                  HiveParse hiveParse = new HiveParse(param);
                  parseSql = hiveParse.parseSql_table();
               } else if ("gauss".equals(dbType)) {
                  GaussParse gaussParse = new GaussParse(param);
                  parseSql = gaussParse.parseSql_table();
               } else if ("hive_tdh".equals(dbType)) {
                  HiveTDHParse hiveTDHParse = new HiveTDHParse(stringObjectMap);
                  parseSql = hiveTDHParse.parseSql_table();
               } else if ("es".equals(dbType)) {
                  ElasticSearchParse esParse = new ElasticSearchParse(param);
                  parseSql = esParse.parseSql_table();
               } else if ("sparksql".equals(dbType)) {
                  SparkSQLParse sparkSQLParse = new SparkSQLParse(param);
                  parseSql = sparkSQLParse.parseSql_table();
               } else if ("mongodb".equals(dbType)) {
                  MongoParse mongoParse = new MongoParse(param);
                  parseSql = mongoParse.parseSql_table();
               }
            } else {
               MySqlParse mySqlParse = new MySqlParse(param);
               parseSql = mySqlParse.parseSql_table();
            }
         } else {
            SqlServerParse sqlServerParse = new SqlServerParse(param);
            parseSql = sqlServerParse.parseSql_table();
         }

         mapUnionObject2String(stringObjectMap, param);
         return "mongodb".equalsIgnoreCase(dbType) ? parseSql : parseSql.replaceAll("\n", " ");
      } catch (Exception e) {
         SQLLogger.log((String)param.get("sql"), e.toString());
         throw e;
      }
   }

   public String desensitization(Map<String, Object> paramObject) throws Exception {
      SQLLogger.log((String)paramObject.get("sql"));

      try {
         String dbType = (String)paramObject.get("dbType");
         String parseSql = "";
         Map<String, String> param = objectMapToStringMap(paramObject);
         if ("oracle".equals(dbType)) {
            OracleParse oracleParse = new OracleParse(param);
            parseSql = oracleParse.parseSql_data();
         } else if (!"sql server".equals(dbType) && !"sqlserver".equals(dbType)) {
            if ("greenplum".equals(dbType)) {
               GreenPlumParse greenPlumParse = new GreenPlumParse(param);
               parseSql = greenPlumParse.parseSql_data();
            } else if ("postgresql".equals(dbType)) {
               PostgreSqlParse postgreSqlParse = new PostgreSqlParse(param);
               parseSql = postgreSqlParse.parseSql_data();
            } else if ("mariadb".equals(dbType)) {
               MariadbParse mariadbParse = new MariadbParse(param);
               parseSql = mariadbParse.parseSql_data();
            } else if ("dm".equals(dbType)) {
               DmParse dmParse = new DmParse(param);
               parseSql = dmParse.parseSql_data();
            } else if ("db2".equals(dbType)) {
               DB2Parse db2Parse = new DB2Parse(param);
               parseSql = db2Parse.parseSql_data();
            } else if (!"mysql".equals(dbType) && !"KUNDB".equals(dbType)) {
               if ("kingbase".equals(dbType)) {
                  KingBaseParse kingBaseParse = new KingBaseParse(param);
                  parseSql = kingBaseParse.parseSql_data();
               } else if ("hive".equals(dbType)) {
                  HiveParse hiveParse = new HiveParse(param);
                  parseSql = hiveParse.parseSql_data();
               } else if ("gauss".equals(dbType)) {
                  GaussParse gaussParse = new GaussParse(param);
                  parseSql = gaussParse.parseSql_data();
               } else if ("hive_tdh".equals(dbType)) {
                  HiveTDHParse hiveTDHParse = new HiveTDHParse(paramObject);
                  parseSql = hiveTDHParse.parseSql_data();
               } else if ("es".equals(dbType)) {
                  ElasticSearchParse esParse = new ElasticSearchParse(param);
                  parseSql = esParse.parseSql_data();
               } else if ("sparksql".equals(dbType)) {
                  SparkSQLParse sparkSQLParse = new SparkSQLParse(param);
                  parseSql = sparkSQLParse.parseSql_data();
               } else if ("mongodb".equals(dbType)) {
                  MongoParse mongoParse = new MongoParse(param);
                  parseSql = mongoParse.parseSql_data();
               }
            } else {
               MySqlParse mySqlParse = new MySqlParse(param);
               parseSql = mySqlParse.parseSql_data();
            }
         } else {
            SqlServerParse sqlServerParse = new SqlServerParse(param);
            parseSql = sqlServerParse.parseSql_data();
         }

         mapUnionString2Object(param, paramObject);
         return "mongodb".equalsIgnoreCase(dbType) ? parseSql : parseSql.replaceAll("\n", " ");
      } catch (Exception e) {
         SQLLogger.log((String)paramObject.get("sql"), e.toString());
         throw e;
      }
   }

   public String addWhereCondition(Map<String, Object> param) {
      SQLLogger.log((String)param.get("sql"));
      String result = "";

      try {
         String dbType = (String)param.get("dbType");
         if ("mysql".equals(dbType) || "KUNDB".equals(dbType)) {
            MySqlParse mySqlParse = new MySqlParse();
            result = mySqlParse.addWhereCondition(param);
         }
      } catch (Exception e) {
         SQLLogger.log((String)param.get("sql"), e.toString());
         e.printStackTrace();
      }

      return result;
   }

   public String rowVisitControl(Map<String, Object> param) {
      SQLLogger.log((String)param.get("sql"));
      String parseSql = "";

      try {
         String dbType = (String)param.get("dbType");
         if ("oracle".equals(dbType)) {
            OracleParse oracleParse = new OracleParse();
            parseSql = oracleParse.rowVisitControl(param);
         } else if (!"sql server".equals(dbType) && !"sqlserver".equals(dbType)) {
            if ("greenplum".equals(dbType)) {
               GreenPlumParse greenPlumParse = new GreenPlumParse();
               parseSql = greenPlumParse.rowVisitControl(param);
            } else if ("gauss".equals(dbType)) {
               GaussParse gaussPlumParse = new GaussParse();
               parseSql = gaussPlumParse.rowVisitControl(param);
            } else if ("postgresql".equals(dbType)) {
               PostgreSqlParse postgreSqlParse = new PostgreSqlParse();
               parseSql = postgreSqlParse.rowVisitControl(param);
            } else if ("kingbase".equals(dbType)) {
               KingBaseParse kingBaseParse = new KingBaseParse();
               parseSql = kingBaseParse.rowVisitControl(param);
            } else if ("mariadb".equals(dbType)) {
               MariadbParse mariadbParse = new MariadbParse();
               parseSql = mariadbParse.rowVisitControl(param);
            } else if (!"mysql".equals(dbType) && !"KUNDB".equals(dbType)) {
               if ("dm".equals(dbType)) {
                  DmParse dmParse = new DmParse();
                  parseSql = dmParse.rowVisitControl(param);
               } else if ("db2".equals(dbType)) {
                  DB2Parse db2Parse = new DB2Parse();
                  parseSql = db2Parse.rowVisitControl(param);
               } else if ("hive".equals(dbType)) {
                  HiveParse hiveParse = new HiveParse();
                  parseSql = hiveParse.rowVisitControl(param);
               } else if ("hive_tdh".equals(dbType)) {
                  HiveTDHParse hiveTDHParse = new HiveTDHParse();
                  parseSql = hiveTDHParse.rowVisitControl(param);
               } else if ("es".equals(dbType)) {
                  ElasticSearchParse esParse = new ElasticSearchParse();
                  parseSql = esParse.rowVisitControl(param);
               } else if ("sparksql".equals(dbType)) {
                  SparkSQLParse sparkSQLParse = new SparkSQLParse();
                  parseSql = sparkSQLParse.rowVisitControl(param);
               } else if ("mongodb".equals(dbType)) {
                  MongoParse mongoParse = new MongoParse();
                  parseSql = mongoParse.rowVisitControl(param);
               }
            } else {
               MySqlParse mySqlParse = new MySqlParse();
               parseSql = mySqlParse.rowVisitControl(param);
            }
         } else {
            SqlServerParse sqlServerParse = new SqlServerParse();
            parseSql = sqlServerParse.rowVisitControl(param);
         }
      } catch (Exception e) {
         e.printStackTrace();
         SQLLogger.log((String)param.get("sql"), e.toString());
      }

      return parseSql;
   }

   public static Map<String, String> objectMapToStringMap(Map<String, Object> map) {
      Map<String, String> stringMap = new HashMap();

      for(Map.Entry<String, Object> entry : map.entrySet()) {
         String key = (String)entry.getKey();
         Object value = entry.getValue();
         if (value != null && value instanceof String) {
            stringMap.put(key, value.toString());
         }
      }

      return stringMap;
   }

   public static void mapUnionString2Object(Map<String, String> map1, Map<String, Object> map2) {
      for(String s : map1.keySet()) {
         if (!map2.containsKey(s)) {
            map2.put(s, map1.get(s));
         }
      }

   }

   public static Map<String, Object> stringMapToObjectMap(Map<String, String> map) {
      Map<String, Object> objectMap = new HashMap();

      for(Map.Entry<String, String> entry : map.entrySet()) {
         String key = (String)entry.getKey();
         String value = (String)entry.getValue();
         if (value != null) {
            objectMap.put(key, value);
         }
      }

      return objectMap;
   }

   public static void mapUnionObject2String(Map<String, Object> map1, Map<String, String> map2) {
      for(String s : map1.keySet()) {
         if (!map2.containsKey(s) && map1.get(s) instanceof String) {
            map2.put(s, (String)map1.get(s));
         }
      }

   }

   public Map<String, Object> parseSqlStructureXY(Map<String, String> param) {
      SQLLogger.log((String)param.get("sql"));
      Map<String, Object> result = new HashMap();

      try {
         String dbType = (String)param.get("dbType");
         String sql = (String)param.get("sql");
         if (!dbType.equalsIgnoreCase("es") && (sql == null || "".equals(sql))) {
            return result;
         }

         if ("mysql".equals(dbType)) {
            MySqlParse mySqlParse = new MySqlParse(param);
            mySqlParse.parseSqlStructureXY(result);
         } else if ("oracle".equals(dbType)) {
            OracleParse oracleParse = new OracleParse(param);
            oracleParse.parseSqlStructureXY(result);
         }
      } catch (Exception e) {
         SQLLogger.log((String)param.get("sql"), e.toString());
         e.printStackTrace();
      }

      return result;
   }

   public String formatSQL(Map<String, String> param) {
      SQLLogger.log((String)param.get("sql"));

      try {
         String dbType = (String)param.get("dbType");
         String sql = (String)param.get("sql");
         if (!dbType.equalsIgnoreCase("es") && (sql == null || "".equals(sql))) {
            return (String)param.get("sql");
         }

         String result = (String)param.get("sql");
         if ("mysql".equals(dbType) || "KUNDB".equals(dbType)) {
            MySqlParse mySqlParse = new MySqlParse(param);
            return mySqlParse.formatSQL(result);
         }

         if ("oracle".equals(dbType)) {
            OracleParse oracleParse = new OracleParse(param);
            return oracleParse.formatSQL(result);
         }

         if ("postgresql".equals(dbType)) {
            PostgreSqlParse postgreSqlParse = new PostgreSqlParse(param);
            return postgreSqlParse.formatSQL(result);
         }

         if ("hive".equals(dbType) || "hive_tdh".equals(dbType)) {
            HiveParse hiveParse = new HiveParse(param);
            return hiveParse.formatSQL(result);
         }

         if ("dm".equals(dbType)) {
            DmParse dmParse = new DmParse(param);
            return dmParse.formatSQL(result);
         }

         if ("db2".equals(dbType)) {
            DB2Parse db2Parse = new DB2Parse(param);
            return db2Parse.formatSQL(result);
         }

         if ("sql server".equals(dbType) || "sqlserver".equals(dbType)) {
            SqlServerParse sqlServerParse = new SqlServerParse(param);
            return sqlServerParse.formatSQL(result);
         }

         if ("kingbase".equals(dbType)) {
            KingBaseParse kingBaseParse = new KingBaseParse(param);
            return kingBaseParse.formatSQL(result);
         }

         if ("mariadb".equals(dbType)) {
            MariadbParse mariadbParse = new MariadbParse(param);
            return mariadbParse.formatSQL(result);
         }

         if ("greenplum".equals(dbType)) {
            GreenPlumParse greenPlumParse = new GreenPlumParse(param);
            return greenPlumParse.formatSQL(result);
         }

         if ("gauss".equals(dbType)) {
            GaussParse gaussParse = new GaussParse(param);
            return gaussParse.formatSQL(result);
         }

         if ("sparksql".equals(dbType)) {
            SparkSQLParse sparkSQLParse = new SparkSQLParse(param);
            return sparkSQLParse.formatSQL(result);
         }
      } catch (Exception e) {
         SQLLogger.log((String)param.get("sql"), e.toString());
         e.printStackTrace();
      }

      return (String)param.get("sql");
   }

   public List<String> parseWheres(Map<String, String> param) {
      SQLLogger.log((String)param.get("sql"));

      try {
         String dbType = (String)param.get("dbType");
         String sql = (String)param.get("sql");
         if (!dbType.equalsIgnoreCase("es") && (sql == null || "".equals(sql))) {
            return new ArrayList();
         }

         String result = (String)param.get("sql");
         if ("mysql".equals(dbType) || "KUNDB".equals(dbType)) {
            MySqlParse mySqlParse = new MySqlParse(param);
            return mySqlParse.parseWheres(result);
         }

         if ("oracle".equals(dbType)) {
            OracleParse oracleParse = new OracleParse(param);
            return oracleParse.parseWheres(result);
         }

         if ("postgresql".equals(dbType)) {
            PostgreSqlParse postgreSqlParse = new PostgreSqlParse(param);
            return postgreSqlParse.parseWheres(result);
         }

         if ("hive".equals(dbType) || "hive_tdh".equals(dbType)) {
            HiveParse hiveParse = new HiveParse(param);
            return hiveParse.parseWheres(result);
         }

         if ("dm".equals(dbType)) {
            DmParse dmParse = new DmParse(param);
            return dmParse.parseWheres(result);
         }

         if ("db2".equals(dbType)) {
            DB2Parse db2Parse = new DB2Parse(param);
            return db2Parse.parseWheres(result);
         }

         if ("sql server".equals(dbType) || "sqlserver".equals(dbType)) {
            SqlServerParse sqlServerParse = new SqlServerParse(param);
            return sqlServerParse.parseWheres(result);
         }

         if ("kingbase".equals(dbType)) {
            KingBaseParse kingBaseParse = new KingBaseParse(param);
            return kingBaseParse.parseWheres(result);
         }

         if ("mariadb".equals(dbType)) {
            MariadbParse mariadbParse = new MariadbParse(param);
            return mariadbParse.parseWheres(result);
         }

         if ("greenplum".equals(dbType)) {
            GreenPlumParse greenPlumParse = new GreenPlumParse(param);
            return greenPlumParse.parseWheres(result);
         }

         if ("gauss".equals(dbType)) {
            GaussParse gaussParse = new GaussParse(param);
            return gaussParse.parseWheres(result);
         }

         if ("es".equals(dbType)) {
            ElasticSearchParse esParse = new ElasticSearchParse(param);
            return esParse.parseWheres(result);
         }

         if ("sparksql".equals(dbType)) {
            SparkSQLParse sparkSQLParse = new SparkSQLParse(param);
            return sparkSQLParse.parseWheres(result);
         }

         if ("mongodb".equals(dbType)) {
            MongoParse mongoParse = new MongoParse(param);
            return mongoParse.parseWheres(result);
         }
      } catch (Exception e) {
         SQLLogger.log((String)param.get("sql"), e.toString());
         e.printStackTrace();
      }

      return new ArrayList();
   }

   public Map<String, Object> parseMongoShellApi2BsonString(Map<String, String> param) {
      Map<String, Object> result = new HashMap();

      try {
         MongoParse mongoParse = new MongoParse(param);
         mongoParse.parseMongoShellApi2BsonString(result);
      } catch (Exception e) {
         SQLLogger.log(param.toString(), e.toString());
         e.printStackTrace();
      }

      return result;
   }

   public Map<String, Object> sqlReplaceForParam(String sql, String dbType, String ip_port, String schema, HashMap<String, String> keyMap) {
      Map<String, Object> hashMap = new HashMap();
      List<SQLStatement> statements = SQLUtils.parseStatements(sql, dbType);
      Scope scope = null;
      if ("postgresql".equals(dbType)) {
         PostgreSqlParse postgreSqlParse = new PostgreSqlParse();
         scope = postgreSqlParse.getScope(ip_port, schema, statements);
      } else if (!"mysql".equals(dbType) && !"mariadb".equals(dbType)) {
         if ("oracle".equals(dbType)) {
            OracleParse oracleParse = new OracleParse();
            scope = oracleParse.getScope(ip_port, schema, statements);
         } else if ("gauss".equals(dbType)) {
            GaussParse gaussParse = new GaussParse();
            scope = gaussParse.getScope(ip_port, schema, statements);
         } else if (!"sql server".equals(dbType) && !"sqlserver".equals(dbType)) {
            if ("greenplum".equals(dbType)) {
               GreenPlumParse parse = new GreenPlumParse();
               scope = parse.getScope(ip_port, schema, statements);
            } else if ("hive".equals(dbType)) {
               HiveParse parse = new HiveParse();
               scope = parse.getScope(ip_port, schema, statements);
            } else if ("dm".equals(dbType)) {
               DmParse parse = new DmParse();
               scope = parse.getScope(ip_port, schema, statements);
            } else if ("kingbase".equals(dbType)) {
               KingBaseParse parse = new KingBaseParse();
               scope = parse.getScope(ip_port, schema, statements);
            } else if ("db2".equals(dbType)) {
               DB2Parse parse = new DB2Parse();
               scope = parse.getScope(ip_port, schema, statements);
            } else if ("spark".equals(dbType)) {
               SparkSQLParse parse = new SparkSQLParse();
               scope = parse.getScope(ip_port, schema, statements);
            }
         } else {
            SqlServerParse parse = new SqlServerParse();
            scope = parse.getScope(ip_port, schema, statements);
         }
      } else {
         MySqlParse mySqlParse = new MySqlParse();
         scope = mySqlParse.getScope(ip_port, schema, statements);
      }

      ReplaceVisitor replaceVisitor = new ReplaceVisitor(scope);
      replaceVisitor.perform(statements);
      ReplaceInfo replaceInfo = scope.getReplaceInfo();
      String prefix = replaceInfo.getPrefix();
      String columnName = replaceInfo.getColumnName();
      ip_port = ip_port.replace(":", "_");
      String key = ip_port + "_" + prefix + "_" + columnName;
      String s = (String)keyMap.get(key);
      String[] split = s.split("#");
      hashMap.put("sql", replaceVisitor.visitReplace((SQLStatement)statements.get(0), replaceInfo, split[0], split[1]));
      hashMap.put("replaceInfo", replaceInfo);
      return hashMap;
   }
}
