package util.sqlparse.visitor.mongo.desensitization;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import util.sqlparse.visitor.mongo.ApiParser;
import util.sqlparse.visitor.mongo.MongoNode;
import util.sqlparse.visitor.mongo.MongoParser;
import util.sqlparse.visitor.mongo.ParseResult;

public class RowVisitController {
   private final String tableRegex;
   private final String column;
   private final String value;
   private final ParseResult result;
   private final Map params;
   private String limit;

   public RowVisitController(ParseResult result, Map params) {
      this.result = result;
      this.params = params;
      Map<String, List<String>> modifyTable = (Map)params.get("modifyTable");
      Map<String, String> tableKeyWord = (Map)params.get("tableKeyWord");
      this.limit = (String)params.get("limit");
      this.tableRegex = (String)tableKeyWord.keySet().iterator().next();
      this.column = (String)tableKeyWord.values().iterator().next();
      this.value = (String)((List)modifyTable.values().iterator().next()).get(0);
   }

   public void perform() {
      if (!this.checkRowVisit()) {
         this.params.put("isMatched", "false");
      } else {
         String sql = (String)this.params.get("sql");
         Pattern pattern = Pattern.compile(this.tableRegex);
         Set<String> collections = this.result.collections;
         ParseResult visitorResult = null;

         for(String collection : collections) {
            if (pattern.matcher(collection).matches()) {
               ApiParser apiParser = new ApiParser();
               MongoNode node = apiParser.convert(sql);
               RowVisitControllerVisitor visitor = new RowVisitControllerVisitor(this.params);
               MongoParser parser = new MongoParser(visitor);
               parser.parse(node);
               visitorResult = visitor.getResult();
               break;
            }
         }

         if (visitorResult != null && visitorResult.isMatched) {
            this.params.put("newSql", visitorResult.newMongoNode.toString());
            this.params.put("isMatched", "true");
         } else {
            this.params.put("newSql", sql);
            this.params.put("isMatched", "false");
         }

      }
   }

   private boolean checkRowVisit() {
      String operateType = (String)this.params.get("operateType");
      if ("select".equals(this.result.sqlType)) {
         if (!"select".equalsIgnoreCase(operateType)) {
            return false;
         }
      } else if ("insert".equals(this.result.sqlType)) {
         if (!"insert".equalsIgnoreCase(operateType)) {
            return false;
         }
      } else if ("update".equals(this.result.sqlType)) {
         if (!"update".equalsIgnoreCase(operateType)) {
            return false;
         }
      } else {
         if (!"delete".equals(this.result.sqlType)) {
            return false;
         }

         if (!"delete".equalsIgnoreCase(operateType)) {
            return false;
         }
      }

      return true;
   }
}
