package util.sqlparse.visitor.es.api;

import com.alibaba.druid.sql.dialect.es.ast.EsParser;
import com.alibaba.druid.sql.dialect.es.ast.EsParserContextBase;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.TerminalNode;
import java.util.List;

public class RequestBuilder {
   private Request request = new Request();

   public static RequestBuilder builder() {
      RequestBuilder instance = new RequestBuilder();
      return instance;
   }

   private RequestBuilder() {
   }

   public RequestBuilder method(Token node) {
      this.request.setMethod(node.getText());
      return this;
   }

   public RequestBuilder method(TerminalNode node) {
      this.request.setMethod(node.getText());
      return this;
   }

   public RequestBuilder path(Token token) {
      if (token == null) {
         return this;
      } else {
         StringBuilder sb = new StringBuilder();
         if (this.request.getPath() != null) {
            sb.append(this.request.getPath());
         }

         sb.append("/");
         sb.append(token.getText());
         this.request.setPath(sb.toString());
         return this;
      }
   }

   public RequestBuilder path(TerminalNode token) {
      if (token == null) {
         return this;
      } else {
         StringBuilder sb = new StringBuilder();
         if (this.request.getPath() != null) {
            sb.append(this.request.getPath());
         }

         sb.append("/");
         sb.append(token.getText());
         this.request.setPath(sb.toString());
         return this;
      }
   }

   public RequestBuilder path(String uriSegs) {
      if (uriSegs != null && uriSegs.length() != 0) {
         StringBuilder sb = new StringBuilder();
         if (this.request.getPath() != null) {
            sb.append(this.request.getPath());
         }

         sb.append("/");
         sb.append(uriSegs);
         this.request.setPath(sb.toString());
         return this;
      } else {
         return this;
      }
   }

   public RequestBuilder path(EsParser.UriSegContext uriSeg) {
      if (uriSeg == null) {
         return this;
      } else {
         StringBuilder sb = new StringBuilder();
         if (this.request.getPath() != null) {
            sb.append(this.request.getPath());
         }

         sb.append("/");
         sb.append(uriSeg.getText());
         this.request.setPath(sb.toString());
         return this;
      }
   }

   public RequestBuilder path(EsParser.UriSegIndexContext uriSeg) {
      if (uriSeg == null) {
         return this;
      } else {
         StringBuilder sb = new StringBuilder();
         if (this.request.getPath() != null) {
            sb.append(this.request.getPath());
         }

         sb.append("/");
         sb.append(uriSeg.getText());
         this.request.setPath(sb.toString());
         return this;
      }
   }

   public RequestBuilder path(List<EsParser.UriSegContext> uriSegs) {
      if (uriSegs != null && uriSegs.size() != 0) {
         StringBuilder sb = new StringBuilder();
         if (this.request.getPath() != null) {
            sb.append(this.request.getPath());
         }

         for(EsParser.UriSegContext uriSeg : uriSegs) {
            sb.append("/");
            sb.append(uriSeg.getText());
         }

         this.request.setPath(sb.toString());
         return this;
      } else {
         return this;
      }
   }

   public RequestBuilder fragment(EsParser.UriFragmentsContext fragment) {
      if (fragment == null) {
         return this;
      } else {
         EsParser.UriFragmentSegmentsContext uriFragmentSegmentsContext = fragment.uriFragmentSegments();
         if (uriFragmentSegmentsContext != null) {
            List<EsParser.UriFragmentSegmentContext> segments = uriFragmentSegmentsContext.uriFragmentSegment();
            if (segments != null && segments.size() > 0) {
               for(EsParser.UriFragmentSegmentContext segmentContext : segments) {
                  String key = null;
                  StringBuilder value = new StringBuilder();

                  for(ParseTree child : segmentContext.children) {
                     TerminalNode node = (TerminalNode)child;
                     int type = node.getSymbol().getType();
                     switch (type) {
                        case 278:
                        case 284:
                           value.append(node.getText());
                           break;
                        case 287:
                           if (key == null) {
                              key = child.getText();
                           } else {
                              value.append(node.getText());
                           }
                     }
                  }

                  if (key != null) {
                     this.request.getQuery().put(key, value.toString());
                  }
               }
            }
         }

         return this;
      }
   }

   public Request build() {
      return this.request;
   }

   public RequestBuilder index(EsParserContextBase indexName) {
      if (indexName == null) {
         return this;
      } else {
         this.request.setIndex(indexName.getText());
         this.request.indexRefs.add(indexName);
         return this;
      }
   }

   public RequestBuilder mapping(EsParserContextBase mapping) {
      if (mapping == null) {
         return this;
      } else {
         this.request.mappingRefs.add(mapping);
         this.request.setIndex(mapping.getText());
         return this;
      }
   }
}
