package util.sqlparse.visitor.es.dense;

import com.alibaba.druid.sql.dialect.es.ast.EsStatementType;
import java.util.Map;
import java.util.regex.Pattern;
import util.sqlparse.visitor.es.dense.data.query.MGetDense;
import util.sqlparse.visitor.es.dense.data.query.MSearchDense;
import util.sqlparse.visitor.es.dense.data.query.QueryDataCountDense;
import util.sqlparse.visitor.es.dense.data.query.QueryDataStatementTermsEnumDense;
import util.sqlparse.visitor.es.dense.data.query.SearchDense;
import util.sqlparse.visitor.es.dense.data.update.UpdateDataDense;
import util.sqlparse.visitor.es.memo.ApiResult;
import util.sqlparse.visitor.es.memo.FieldMemo;
import util.sqlparse.visitor.es.memo.MappingMemo;

public class Desensitizor {
   public static void tableDense(Map params) {
      ParamContext base = new ParamContext(params);
      Denseable dense = create(base);
      ParamContext.TableDenseContext context = new ParamContext.TableDenseContext(params);
      if (dense != null) {
         dense.denseTable(context);
         ApiResult api = context.getApi();
         String table = context.replaceTable();
         Pattern p = Pattern.compile(table);

         for(MappingMemo tableMemo : api.getTables()) {
            if (tableMemo != null && tableMemo.name != null && tableMemo.name.length() != 0) {
               String name = tableMemo.flatFullName();
               if (p.matcher(name).matches()) {
                  params.put("isMatched", "true");
                  break;
               }

               if (p.matcher(tableMemo.name).matches()) {
                  params.put("isMatched", "true");
                  break;
               }
            }
         }
      }

      params.putAll(context);
   }

   public static void columnDense(Map params) {
      ParamContext base = new ParamContext(params);
      Denseable dense = create(base);
      ParamContext.ColumnDenseContext context = new ParamContext.ColumnDenseContext(params);
      if (dense != null) {
         dense.denseColumn(context);
      }

      params.putAll(context);
   }

   public static void dataDense(Map params) {
      ParamContext base = new ParamContext(params);
      Denseable dense = create(base);
      ParamContext.DenseAllContext context = new ParamContext.DenseAllContext(params);
      if (dense != null) {
         dense.denseData(context);
      }

      params.putAll(context);
   }

   public static void rowDense(Map params) {
      ParamContext base = new ParamContext(params);
      Denseable dense = create(base);
      ParamContext.RowDenseContext context = new ParamContext.RowDenseContext(params);
      if (dense != null) {
         dense.denseRow(context);
         ApiResult api = context.getApi();
         Map<String, String> tableKeyWord = context.tableKeyWord();
         String table = (String)tableKeyWord.keySet().iterator().next();
         String col = (String)tableKeyWord.values().iterator().next();
         Pattern p = Pattern.compile(table + "\\." + col);

         for(FieldMemo fieldMemo : api.getFields()) {
            if (fieldMemo != null && fieldMemo.name != null && fieldMemo.name.length() != 0) {
               String name = fieldMemo.tableName();
               if (p.matcher(name).matches()) {
                  params.put("isMatched", "true");
                  break;
               }
            }
         }
      }

   }

   static Denseable create(ParamContext ctx) {
      ApiResult api = ctx.getApi();
      EsStatementType type = api.stmtType;
      Denseable dense = null;
      switch (type) {
         case searchDataQuery:
            dense = new SearchDense();
            break;
         case msearchQuery:
            dense = new MSearchDense();
            break;
         case mgetQuery:
            dense = new MGetDense();
            break;
         case updateData:
            dense = new UpdateDataDense();
            break;
         case countQuery:
            dense = new QueryDataCountDense();
            break;
         case termsEnumQuery:
            dense = new QueryDataStatementTermsEnumDense();
            break;
         default:
            dense = new CommonDense();
      }

      return dense;
   }
}
