package util.sqlparse.visitor.es.dense.data.query;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.druid.sql.dialect.es.ast.EsParser;
import com.alibaba.druid.sql.dialect.es.ast.EsParserContextBase;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import util.sqlparse.visitor.es.dense.Denseable;
import util.sqlparse.visitor.es.dense.EsBuilder;
import util.sqlparse.visitor.es.dense.ParamContext;
import util.sqlparse.visitor.es.memo.ApiResult;
import util.sqlparse.visitor.es.memo.FlowType;

public class MGetDense extends Denseable {
   @FlowType(FlowType.FlowTypeValue.up)
   public void denseTable(ParamContext.TableDenseContext params) {
      ApiResult api = params.getApi();
      EsParser.StatementContext statement = (EsParser.StatementContext)api.getStatement();
      EsParser.QueryDataStatementContext query = statement.queryDataStatement();
      EsParser.QueryDataStatementMGETContext search = query.queryDataStatementMGET();
      if (search != null) {
         this.changeHttp(search, api);
         super.denseTable(params);
      }
   }

   private void changeHttp(EsParser.QueryDataStatementMGETContext ctx, ApiResult api) {
      EsParser.UriSegIndexContext index = ctx.indexName;
      EsParser.UriSegIndexContext mapping = ctx.mappingName;
      EsBuilder builder = EsBuilder.builder();
      EsParserContextBase uriIndex = this.buildEntityUri(builder, api.getSchemas());
      builder.reset();
      if (index != null) {
         builder.enter(index).replaceMe(uriIndex);
      } else {
         builder.enter(ctx).at(1).slash().append(2, uriIndex);
      }

      EsParserContextBase uriMapping = this.buildEntityUri(builder, api.getTables());
      builder.reset();
      if (mapping != null) {
         builder.enter(mapping).replaceMe(uriMapping);
      } else if (uriMapping != null) {
         builder.enter(ctx).at(3).slash().append(4, uriMapping);
      }

   }

   @FlowType(FlowType.FlowTypeValue.down)
   public void denseRow(ParamContext.RowDenseContext params) {
      Map<String, List<String>> modifyTable = params.modifyTable();
      if (modifyTable != null && modifyTable.size() != 0) {
         Map<String, String> tableKeyWord = params.tableKeyWord();
         if (tableKeyWord != null && tableKeyWord.size() != 0) {
            String table = (String)tableKeyWord.keySet().iterator().next();
            String value = (String)((List)modifyTable.values().iterator().next()).get(0);
            String col = (String)tableKeyWord.values().iterator().next();
            if (value != null) {
               String response = params.response();
               Pattern pat = this.createColumnPattern(null, table, col);
               JSONObject data = JSON.parseObject(response);
               JSONArray responses = data.getJSONArray("docs");
               if (responses != null && responses.size() != 0) {
                  for(Object dataItem : responses) {
                     if (dataItem instanceof JSONObject) {
                        JSONObject hits = (JSONObject)dataItem;
                        String type = hits.getString("_type");
                        String index = hits.getString("_index");
                        JSONObject source = hits.getJSONObject("_source");
                        StringBuilder path = new StringBuilder();
                        path.append(index).append(".").append(type).append(".");
                        this.denseRowData(pat, source, path, value);
                     }
                  }

                  params.setResponse(data.toString());
               }
            }
         }
      }
   }

   @FlowType(FlowType.FlowTypeValue.down)
   public void denseColumn(ParamContext.ColumnDenseContext params) {
      String replaceSchema = params.replaceSchema();
      String replaceTable = params.replaceTable();
      String replaceColumn = params.replaceColumn();
      String expression = params.expression();
      String response = params.response();
      Pattern pat = this.createColumnPattern(replaceSchema, replaceTable, replaceColumn);
      JSONObject data = JSON.parseObject(response);
      JSONArray responses = data.getJSONArray("docs");
      if (responses != null && responses.size() != 0) {
         for(Object dataItem : responses) {
            if (dataItem instanceof JSONObject) {
               JSONObject hits = (JSONObject)dataItem;
               String type = hits.getString("_type");
               String index = hits.getString("_index");
               JSONObject source = hits.getJSONObject("_source");
               StringBuilder path = new StringBuilder();
               path.append(index).append(".").append(type).append(".");
               this.denseColumnData(pat, source, expression, path, params);
            }
         }

         params.setResponse(data.toString());
      }
   }

   public void denseData(ParamContext.DenseAllContext params) {
      ParamContext.ColumnDenseContext columnDenseContext = new ParamContext.ColumnDenseContext(params);
      this.denseColumn(columnDenseContext);
      params.putAll(columnDenseContext);
   }
}
