package test;

import bean.Column;
import bean.DataBase;
import bean.Schema;
import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.SQLUtils;
import java.io.IOException;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import util.JdbcUtil;
import util.SqlUtil;
import util.StringJoin;
import util.getdata.DatabaseCache;

public class DB2Test {
   public static void main(String[] args) throws SQLException, InterruptedException, IOException {
      String content = "{\n      \"ip_port\": \"192.168.2.127:50000\",\n      \"url\": \"jdbc:db2://192.168.2.127:50000/test\",\n      \"username\": \"fooxr\",\n      \"password\": \"admin\",\n      \"isIgnorecase\":\"1\",\n      \"dbType\": \"db2\",\n      \"redisMode\": \"none\",\n      \"redisIp\": \"192.168.2.105\",\n      \"redisPort\": \"6379\",\n      \"redisUsername\": \"\",\n      \"redisPassword\": \"redis\",\n      \"redisDatabase\": \"0\",\n      \"excludeSchema\": [\"encryption_test2\",\"ghca_static_develop\",\"ghca_static_develop_test\",\"pg_catalog\",\"information_schema\",\"sysaudit\",\"sysmac\",\"sys\",\"sysmac\",\"sysmac\",\"sysmac\",\"ry\"]\n    }";
      JdbcUtil.initData(content);
      Thread.sleep(3000L);
      DB2Test myTest = new DB2Test();
      myTest.test();
   }

   public void testCache() throws InterruptedException {
      DataBase dataBase = (DataBase)JdbcUtil.dataBaseList.get(0);
      DatabaseCache simpleCache = dataBase.simpleCache;
      Schema ry = simpleCache.getSchema("ry");
      System.out.println(ry == null ? "" : ry.getName());
      List<Column> columns = simpleCache.getColumns("ry", "a");
      System.out.println(columns == null ? 0 : columns.size());

      for(Column column : columns) {
         System.out.println(column.getDigits());
      }

   }

   public String inputSql() {
      String sql = "";
      sql = "update sys_user SET login_ip = '192.168.2.127',login_date = '2023-08-08',update_time = CURRENT TIMESTAMP where user_id = 1";
      sql = "insert into sys_logininfor (info_id, login_name, status, ipaddr, login_location, browser, os, msg, login_time) values (?, ?, ?, ?, ?, ?, ?, ?, CURRENT TIMESTAMP)";
      return sql;
   }

   public void test() {
      for(int i = 0; i < 1; ++i) {
         String sql = this.inputSql();
         Map<String, String> params = new HashMap();
         params.put("sql", sql);
         params.put("dbType", "db2");
         params.put("schema", "RY");
         params.put("url", "jdbc:db2://192.168.2.127:50000/test:currentSchema=RY");
         params.put("replaceSchema", ".*");
         params.put("replaceNewTable", "people_bk");
         params.put("replaceTable", ".*");
         params.put("replaceColumn", ".*");
         params.put("expression", "concat(substr(${value},1,1),'**')");
         params.put("configPath", "D:/masking-mysql.properties");
         params.put("limit", "3");
         Map<String, String> map = new HashMap();
         map.put("ghca31.AT_TEST.name", "替1");
         map.put("ghca31.AT_TEST2.name", "替2");
         map.put("ghca31.AT_TEST3.name", "替3");
         map.put("ghca31.AT_TEST.name", "替4");
         map.put("ghca31.AT_TEST2.name", "替5");
         map.put("ghca31.AT_TEST3.name", "替6");
         map.put("ghca_classify_encrytest.T_CONSOLE_DICTIONARY.value", "替7");
         Map<String, List<String>> modifyTable = new HashMap();
         List<String> vals = new ArrayList();
         vals.add("張三");
         modifyTable.put("tB1", vals);
         Map<String, String> tableKeyWord = new HashMap();
         Map<String, Object> param = new HashMap(params);
         param.put("modifyTable", modifyTable);
         param.put("tableKeyWord", tableKeyWord);
         tableKeyWord.put("tB1", "\"fD\"");
         param.put("operateType", "select");
         param.put("limit", "10");
         SqlUtil sqlUtil = new SqlUtil();
         System.out.println("..............row visit.....................................");
         System.out.println("\n\n[0]********************************************************************************");
         System.out.println("--------------------- source sql    ------------------------------------------------");
         System.out.println(sql);
         System.out.println("---------------------/source sql    ------------------------------------------------");
         System.out.println("---------------------parse structure------------------------------------------------");
         Map<String, Object> s2 = sqlUtil.parseSqlStructure(params);
         System.out.println("\n\n====schemaMap====");
         Map<String, Object> schemaMap = (Map)s2.get("schemaMap");

         for(Map.Entry<String, Object> item : schemaMap.entrySet()) {
            System.out.println((String)item.getKey() + "\t" + item.getValue());
         }

         System.out.println("\n\n====tableMap====");
         Map<String, Object> tableMap = (Map)s2.get("tableMap");

         for(Map.Entry<String, Object> item : tableMap.entrySet()) {
            System.out.println((String)item.getKey() + "\t" + item.getValue());
         }

         System.out.println("\n\n====whereMap====");
         Map<String, Object> whereMap = (Map)s2.get("whereMap");
         if (whereMap != null) {
            for(Map.Entry<String, Object> item : whereMap.entrySet()) {
               System.out.println((String)item.getKey() + "\t" + item.getValue());
            }
         }

         System.out.println("\n\n====whereList====");
         ArrayList<Map<String, Object>> whereList = (ArrayList)s2.get("whereList");
         if (whereList != null) {
            for(Map<String, Object> where : whereList) {
               for(Map.Entry<String, Object> item : where.entrySet()) {
                  System.out.println((String)item.getKey() + "\t" + item.getValue());
               }
            }
         }

         System.out.println("\n\n====columnList====");
         ArrayList<Column> columnList = (ArrayList)s2.get("columnList");
         String[] fields = new String[]{"columnName", "columnAlisa", "fullName", "nowName", "dataType", "schema", "table", "value", "expr"};
         int[] size = this.max(fields, columnList);

         for(int j = 0; j < fields.length; ++j) {
            fields[j] = String.format("%" + size[j] + "s", fields[j]);
         }

         System.out.println(StringJoin.join(fields, "  "));

         for(Column item : columnList) {
            StringBuilder output = new StringBuilder();
            this.printColumn(item, output, size);
            System.out.println(output);
         }

         System.out.println("\n\n====SQL====");
         System.out.println(s2.get("sql"));
         System.out.println("\n\n====/SQL====");
         System.out.println("---------------------/parse structure------------------------------------------------");
      }

   }

   private double invoke(String sql) {
      try {
         long c = System.nanoTime();
         SQLUtils.parseStatements(sql, DbType.mysql);
         long c1 = System.nanoTime();
         double c2 = (double)(c1 - c) / (double)1000000.0F;
         return c2;
      } catch (Exception e) {
         e.printStackTrace();
         return (double)0.0F;
      }
   }

   private void printColumn(Column col, StringBuilder s, int[] size) {
      s.append(this.format(col.getColumnName(), size[0])).append("  ").append(this.format(col.getColumnAlisa(), size[1])).append("  ").append(this.format(col.getFullName(), size[2])).append("  ").append(this.format(col.getNowName(), size[3])).append("  ").append(this.format(col.getDataType(), size[4])).append("  ").append(this.format(col.getSchema(), size[5])).append("  ").append(this.format(col.getTable(), size[6])).append("  ").append(this.format(col.getValue(), size[7])).append("  ").append(this.format(col.getExpr(), size[8]));
   }

   private String format(Object value, int size) {
      return String.format("%" + size + "s", value);
   }

   private int[] max(String[] fields, List<Column> columns) {
      int[] size = new int[fields.length];

      try {
         for(int i = 0; i < fields.length; ++i) {
            String name = fields[i];
            name = (name.charAt(0) + "").toUpperCase() + name.substring(1);
            String method = "get" + name;
            Method m = Column.class.getDeclaredMethod(method);
            int max = name.length();
            if (columns != null) {
               for(Column column : columns) {
                  Object value = m.invoke(column);
                  if (value != null) {
                     int s = value.toString().length();
                     max = max < s ? s : max;
                  }
               }
            }

            size[i] = max;
         }
      } catch (Exception e) {
         e.printStackTrace();
      }

      return size;
   }
}
