package com.palacesun.engine.wrapper;

import com.palacesun.engine.common.PreparedStatementInformation;
import com.palacesun.engine.test.TestJdbcEventListener;
import com.palacesun.masking.tools.EngineUtil;
import com.palacesun.masking.vo.Columninfo;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;
import util.SqlUtil;

public class LikeReplaceSql {
   public static HashMap<String, String> keyMap = new HashMap();

   public static Map<String, Object> sqlLikeReplace(PreparedStatementInformation statementInformation) {
      Map<String, Object> map = new HashMap();
      String sql = statementInformation.getSql();
      if (!sql.toLowerCase().contains(" like ")) {
         map.put("sql", sql);
         return map;
      } else {
         String dbType = "";

         try {
            dbType = getDbType(statementInformation, dbType);
            Connection connection = statementInformation.getConnectionInformation().getConnection();
            String urlTemp = connection.getMetaData().getURL();
            String ip = (String)TestJdbcEventListener.getIpAndPort(urlTemp).get("ip");
            String port = (String)TestJdbcEventListener.getIpAndPort(urlTemp).get("port");
            String schema = "";
            if ("oracle".equals(dbType)) {
               schema = connection.getMetaData().getUserName();
            } else if (!"postgresql".equals(dbType) && !"greenplum".equals(dbType) && !"gauss".equals(dbType)) {
               if ("sql server".equals(dbType)) {
                  String url = connection.getMetaData().getURL();
                  if (url.indexOf("applicationName") > 0) {
                     schema = url.substring(url.indexOf("applicationName") + "applicationName".length() + 1);
                     if (schema.indexOf(";") != -1) {
                        schema = schema.substring(0, schema.indexOf(";"));
                     }
                  } else {
                     schema = "dbo";
                  }
               } else if ("dm".equals(dbType)) {
                  String url = connection.getMetaData().getURL();
                  if (url.toLowerCase().contains("schema=")) {
                     schema = url.substring(url.toLowerCase().indexOf("schema=") + 7);
                  } else {
                     int from = url.indexOf("://");
                     int end = url.indexOf("?");
                     String address = end == -1 ? url.substring(from + 3) : url.substring(from + 3, end);
                     int idx = address.lastIndexOf("/");
                     schema = address.substring(idx + 1);
                  }
               } else if ("db2".equals(dbType)) {
                  Statement stmt = connection.createStatement();
                  ResultSet rs = stmt.executeQuery("SELECT CURRENT SCHEMA FROM SYSIBM.SYSDUMMY1");
                  if (rs.next()) {
                     schema = rs.getString(1).trim();
                  } else {
                     schema = connection.getMetaData().getUserName();
                  }

                  rs.close();
                  stmt.close();
               } else if ("kingbase".equals(dbType)) {
                  String url = connection.getMetaData().getURL();
                  if (url.indexOf("searchpath") > 0) {
                     schema = url.substring(url.indexOf("searchpath") + 11);
                  } else if (url.indexOf("currentSchema") > 0) {
                     schema = url.substring(url.indexOf("currentSchema") + 14);
                  } else {
                     schema = "public";
                  }
               } else if ("mysql".equals(dbType)) {
                  String url = connection.getMetaData().getURL();
                  int from = url.indexOf("://");
                  int end = url.indexOf("?");
                  String address = end == -1 ? url.substring(from + 3) : url.substring(from + 3, end);
                  int idx = address.lastIndexOf("/");
                  schema = address.substring(idx + 1);
               } else if ("mariadb".equals(dbType)) {
                  String url = connection.getMetaData().getURL();
                  int from = url.indexOf("://");
                  int end = url.indexOf("?");
                  String address = end == -1 ? url.substring(from + 3) : url.substring(from + 3, end);
                  int idx = address.lastIndexOf("/");
                  schema = address.substring(idx + 1);
               } else if ("hive".equals(dbType)) {
                  String url = connection.getMetaData().getURL();
                  int from = url.indexOf("://");
                  int end = url.indexOf("?");
                  String address = end == -1 ? url.substring(from + 3) : url.substring(from + 3, end);
                  int idx = address.lastIndexOf("/");
                  schema = address.substring(idx + 1);
               } else {
                  schema = connection.getCatalog();
               }
            } else {
               String url = connection.getMetaData().getURL();
               if (url.indexOf("searchpath") > 0) {
                  schema = url.substring(url.indexOf("searchpath") + 11);
               } else if (url.indexOf("currentSchema") > 0) {
                  schema = url.substring(url.indexOf("currentSchema") + 14);
               } else {
                  schema = "public";
               }
            }

            SqlUtil sqlUtil = new SqlUtil();

            for(Map.Entry<String, Object> entry : EngineUtil.encryptionMap.entrySet()) {
               Columninfo columnSecret = (Columninfo)entry.getValue();
               keyMap.put(entry.getKey(), columnSecret.getEncryptiontype() + "#" + columnSecret.getSecretkey());
            }

            map = sqlUtil.sqlReplaceForParam(sql, dbType, ip + ":" + port, schema, keyMap);
         } catch (Exception e1) {
            e1.printStackTrace();
         }

         return map;
      }
   }

   private static String getDbType(PreparedStatementInformation statementInformation, String dbType) throws Exception {
      try {
         String hiveurl = statementInformation.getConnectionInformation().getUrl();
         if (hiveurl.toLowerCase().contains("hive")) {
            return "hive";
         } else {
            String driverName = statementInformation.getConnectionInformation().getConnection().getMetaData().getDriverName();
            if (driverName.toLowerCase().contains("mysql")) {
               dbType = "mysql";
            } else if (driverName.toLowerCase().contains("oracle")) {
               dbType = "oracle";
            } else if (driverName.toLowerCase().contains("postgresql")) {
               String url = statementInformation.getConnectionInformation().getConnection().getMetaData().getURL();
               if (url.contains("gauss")) {
                  dbType = "gauss";
                  return dbType;
               }

               if (url.contains("greenplum")) {
                  dbType = "greenplum";
                  return dbType;
               }

               dbType = "postgresql";
            } else if (driverName.toLowerCase().contains("hive")) {
               dbType = "hive";
            } else if (driverName.toLowerCase().contains("dm")) {
               dbType = "dm";
            } else if (driverName.toLowerCase().contains("ibm")) {
               dbType = "db2";
            } else if (driverName.toLowerCase().contains("sql server")) {
               dbType = "sql server";
            } else if (driverName.toLowerCase().contains("kingbase")) {
               dbType = "kingbase";
            }

            return dbType;
         }
      } catch (Exception e) {
         e.printStackTrace();
         throw e;
      }
   }
}
