package util.sqlparse;

import bean.Column;
import bean.DataBase;
import bean.Table;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.collections.CollectionUtils;
import util.JdbcUtil;
import util.RedisUtil;
import util.sqlparse.visitor.common.bean.ValueInfo;
import util.sqlparse.visitor.common.memo.FieldMemo;
import util.sqlparse.visitor.mongo.ApiParser;
import util.sqlparse.visitor.mongo.ParseResult;
import util.sqlparse.visitor.mongo.desensitization.Desensitization;

public class MongoParse {
   public static final String DB_TYPE = "mongo";
   public List<Column> columnList = new ArrayList();
   public Map<String, String> tableMap = new HashMap();
   public Map<String, String> schemaMap = new HashMap();
   public Map<String, List<ParseResult.RoleDb>> userMap = new HashMap();
   public Map<String, Object> whereMap = new HashMap();
   public List<Map<String, Object>> whereList = new ArrayList();
   public Map<String, String> params;

   public MongoParse() {
   }

   public MongoParse(Map<String, String> params) {
      this.params = params;
   }

   public Map<String, Object> parseSqlStructure(Map<String, Object> param) {
      return this.parseSqlStructureAndReplace(param, (List)null, false);
   }

   public Map<String, Object> parseSqlStructureAndReplace(Map<String, Object> param, List<Map> repalceMap, boolean replace) {
      String sql = (String)this.params.get("sql");
      String permission = (String)this.params.get("permission");
      String url = (String)this.params.get("url");
      String schema = (String)this.params.get("schema");
      String ip_port = url.split("/")[2];
      DataBase dataBase = new DataBase();

      for(DataBase db : JdbcUtil.dataBaseList) {
         if (ip_port.equalsIgnoreCase(db.getIp_port())) {
            dataBase = db;
            break;
         }
      }

      ApiParser parser = new ApiParser();
      ParseResult parse = parser.parse(sql, dataBase, schema);
      param.put("sh-sql", parse.api);

      for(String table : parse.collections) {
         String schemaName = this.getSchemaByCollection(dataBase, table);
         this.schemaMap.put(table, schemaName);
         this.tableMap.put(table, table);
      }

      for(Map.Entry<String, ParseResult.Column> entry : parse.columns.entrySet()) {
         ParseResult.Column value = (ParseResult.Column)entry.getValue();
         if (value.isOutput) {
            Column column = new Column();
            column.setSchema((String)this.schemaMap.get(value.collection));
            column.setColumnName(String.format("%s.%s", value.collection, value.name));
            column.setTable(value.collection);
            column.setColumnAlisa(column.getColumnName());
            column.setSubQuery(false);
            this.columnList.add(column);
         }
      }

      for(Map.Entry<String, List<ParseResult.RoleDb>> entry : parse.user.entrySet()) {
         this.userMap.put(entry.getKey(), entry.getValue());
      }

      if (replace) {
         parser.replace(parse.values, repalceMap);
      }

      for(ValueInfo value : parse.values) {
         FieldMemo field = value.field;
         this.whereMap.put(field.name, value.value.toString());
         Map<String, Object> map = new HashMap();
         map.put("column", field.getAtomName());
         map.put("columnValue", value.value.toString());
         map.put("type", value.operator);
         map.put("value", value);
         this.whereList.add(map);
      }

      param.put("schemaMap", this.schemaMap);
      param.put("tableMap", this.tableMap);
      param.put("columnList", this.columnList);
      param.put("userMap", this.userMap);
      param.put("type", parse.sqlType.toLowerCase());
      param.put("whereList", this.whereList);
      param.put("whereMap", this.whereMap);
      param.put("sql", parse.newMongoNode.toString());
      return param;
   }

   private String getSchemaByCollection(DataBase dataBase, String collection) {
      if (!dataBase.isRedis()) {
         Map<String, Table> tables = dataBase.simpleCache.getTables();
         if (CollectionUtils.isEmpty(Collections.singleton(tables))) {
            return "";
         }

         for(String key : tables.keySet()) {
            String[] split = key.split("--->");
            if (collection.equals(split[1])) {
               return split[0];
            }
         }
      } else {
         Set<String> tableKeys = RedisUtil.getTableKeys(dataBase, collection);
         Iterator var8 = tableKeys.iterator();
         if (var8.hasNext()) {
            String tableKey = (String)var8.next();
            String[] split = tableKey.split(":");
            return split[3];
         }
      }

      return null;
   }

   public String parseSql_column() {
      Desensitization desensitization = new Desensitization();
      Map map = desensitization.parseColumn(this.params);
      return (String)map.get("newSql");
   }

   public String parseSql_table() {
      try {
         Desensitization desensitization = new Desensitization();
         desensitization.parseTable(this.params);
      } catch (Exception throwables) {
         throwables.printStackTrace();
      }

      return (String)this.params.get("newSql");
   }

   public String parseSql_data() {
      Desensitization desensitization = new Desensitization();
      Map map = desensitization.parseData(this.params);
      return (String)map.get("newSql");
   }

   public String rowVisitControl(Map<String, Object> param) throws SQLException {
      Desensitization desensitization = new Desensitization();
      Map map = desensitization.parseRowVisit(param);
      return (String)map.get("newSql");
   }

   public Map<String, Object> parseMongoShellApi2BsonString(Map<String, Object> param) {
      String sh_sql = (String)this.params.get("sh-sql");
      String url = (String)this.params.get("url");
      String schema = (String)this.params.get("schema");
      String ip_port = url.split("/")[2];
      DataBase dataBase = new DataBase();

      for(DataBase db : JdbcUtil.dataBaseList) {
         if (ip_port.equalsIgnoreCase(db.getIp_port())) {
            dataBase = db;
            break;
         }
      }

      ApiParser parser = new ApiParser();
      String bsonString = parser.encode(sh_sql, dataBase, schema);
      param.put("bsonString", bsonString);
      return param;
   }

   public List<String> parseWheres(String bson) {
      if (bson != null && bson.length() != 0) {
         ApiParser parser = new ApiParser();
         return parser.where(bson);
      } else {
         return new ArrayList();
      }
   }
}
