package test;

import bean.Column;
import bean.DataBase;
import bean.Schema;
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 org.apache.commons.collections.CollectionUtils;
import util.JdbcUtil;
import util.SqlUtil;
import util.StringJoin;
import util.getdata.DatabaseCache;
import util.sqlparse.visitor.mongo.ParseResult;

public class MongoTest {
   public static void main(String[] args) throws SQLException, InterruptedException, IOException {
      String content = "{\n      \"ip_port\": \"192.168.2.228:27017\",\n      \"url\": \"jdbc:mongodb://192.168.2.228:27017/test\",\n      \"username\": \"\",\n      \"isIgnorecase\":\"0\",\n      \"password\": \"\",\n      \"dbType\": \"mongodb\",\n      \"servername\": \"test\",\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);
      MongoTest myTest = new MongoTest();
      myTest.test();
   }

   public void test() 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());
      Map<String, String> params = new HashMap();
      params.put("dbType", "mongodb");
      params.put("schema", "test");
      params.put("url", "jdbc:mongodb://192.168.2.228:27017/test");
      params.put("replaceSchema", ".*");
      params.put("replaceNewTable", "people_bk");
      params.put("replaceTable", ".*");
      params.put("replaceColumn", ".*");
      params.put("expression", "concat(substr(${value},1,1),'**')");
      params.put("limit", "3");
      String sql = "{\"updateUser\": \"test1\", \"pwd\": \"123123\", \"writeConcern\": {\"w\": \"majority\", \"wtimeout\": 600000.0}, \"digestPassword\": true, \"lsid\": {\"id\": {\"$binary\": {\"base64\": \"Fvvg6A6IRsefOjczTKXvoA==\", \"subType\": \"04\"}}}, \"$db\": \"test\"}\n";
      params.put("sql", sql);
      SqlUtil sqlUtil = new SqlUtil();
      sqlUtil.parseSqlStructure(params);
      System.out.println("...................................................");
      System.out.println("\n\n[0]********************************************************************************");
      System.out.println("--------------------- source sql    ------------------------------------------------");
      System.out.println(sql);
      System.out.println("---------------------/source sql    ------------------------------------------------");
      System.out.println("略");
      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====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====userMap====");
      System.out.println("user      role       db");
      Map<String, List<ParseResult.RoleDb>> userMap = (Map)s2.get("userMap");

      for(Map.Entry<String, List<ParseResult.RoleDb>> item : userMap.entrySet()) {
         List<ParseResult.RoleDb> list = (List)item.getValue();
         if (CollectionUtils.isNotEmpty(list)) {
            for(int i = 0; i < list.size(); ++i) {
               System.out.println((String)item.getKey() + "\t" + ((ParseResult.RoleDb)list.get(i)).role + "\t" + ((ParseResult.RoleDb)list.get(i)).db);
            }
         } else {
            System.out.println((String)item.getKey());
         }
      }

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

   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;
   }
}
