package util.getdata;

import bean.Column;
import bean.DataBase;
import bean.Schema;
import bean.Table;
import bean.View;
import com.alibaba.druid.sql.dialect.es.visitor.EsUtils;
import com.alibaba.druid.sql.dialect.es.visitor.MappingTree;
import com.alibaba.druid.util.Base64;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicHeader;

public class CacheEs extends CacheData {
   private static final String DEF_SCHEMA_NAME = "default";
   private static final String DEF_TABLE_NAME = "_doc";
   private static Set<String> EXCLUDE_SCHEMAS = new HashSet();

   public CacheEs(DataBase dataBase, CountDownLatch cdl) {
      super(dataBase, cdl);
   }

   public void run() {
      System.out.println("es开始缓存");

      try {
         this.cacheWriteToRedis();
      } catch (Exception e) {
         e.printStackTrace();
      } finally {
         this.getCdl().countDown();
         System.out.println("es结束缓存");
      }

   }

   public List<Schema> cacheToMemory() throws IOException, SQLException {
      String mappings = this.getMappings();
      List<Schema> schemas = this.parseTables(mappings);
      return schemas;
   }

   private List<Schema> parseTables(String body) throws SQLException {
      List<Schema> schemaList = this.getSchema((Statement)null);
      if (body != null && body.length() != 0) {
         MappingTree mapping = EsUtils.parseMappingTree(body);
         List<MappingTree> fields = mapping.getFlatValues();
         String schemaName = "";
         Schema lastSchema = null;
         String tableName = "";
         Table lastTable = null;
         List<Column> columns = null;

         for(MappingTree field : fields) {
            if (field.getIndex() != null) {
               if (EXCLUDE_SCHEMAS.contains(field.getIndex())) {
                  tableName = "";
                  lastSchema = null;
               } else {
                  if (!field.getIndex().equals(schemaName)) {
                     Schema schema = new Schema(field.getIndex());
                     schema.setTableList(new ArrayList());
                     schemaList.add(schema);
                     lastSchema = schema;
                     schemaName = schema.getName();
                     tableName = "";
                  }

                  if (field.getMapping() == null) {
                     tableName = "";
                  } else {
                     if (!field.getMapping().equals(tableName)) {
                        Table table = new Table(field.getMapping(), schemaName);
                        lastSchema.getTableList().add(table);
                        table.setColumnList(new ArrayList());
                        tableName = table.getName();
                        lastTable = table;
                     }

                     if (field.getType() != MappingTree.Type.index && field.getType() != MappingTree.Type.mapping) {
                        Column column = new Column();
                        column.setSchema(schemaName);
                        column.setTable(tableName);
                        column.setColumnName(field.getName());
                        column.setDataType(field.getDataType());
                        column.setColumnType(field.getDataType());
                        lastTable.getColumnList().add(column);
                     }
                  }
               }
            }
         }

         return schemaList;
      } else {
         return schemaList;
      }
   }

   private String getVersion() throws IOException {
      String url1 = this.DataBase.getUrl().replace("/{schema}", "");
      String version = "";
      HttpClient client = HttpClientBuilder.create().build();
      RequestConfig.Builder builder = RequestConfig.custom();
      builder.setConnectTimeout(180000);
      builder.setAuthenticationEnabled(true);
      builder.setConnectionRequestTimeout(180000);
      RequestConfig config = builder.build();
      HttpGet get1 = new HttpGet(url1);
      get1.setConfig(config);
      Auth auth = new BasicAuth(this.DataBase.getUsername(), this.DataBase.getPassword());
      get1.setHeader(auth.getHeader());
      InputStream stream = null;
      ByteArrayOutputStream output = null;

      try {
         HttpResponse response = client.execute(get1);
         HttpEntity entity = response.getEntity();
         Header encoding = entity.getContentEncoding();
         if (encoding == null) {
            String var10000 = "UTF-8";
         } else {
            encoding.getValue();
         }

         stream = entity.getContent();
         output = new ByteArrayOutputStream();
         int read = 0;

         while((read = stream.read()) != -1) {
            output.write(read);
         }

         output.flush();
         String e = output.toString();
         e = e.replace("{", "").replace("}", "").replace("\n", "").replaceAll(" +", "").replace("\"", "").replace(",", ":");
         String[] earray = e.split(":");

         for(int i = 0; i < earray.length; ++i) {
            if ("number".equals(earray[i]) && i + 1 < earray.length) {
               version = earray[i + 1];
            }
         }
      } catch (IOException e) {
         e.printStackTrace();
         throw e;
      } finally {
         if (stream != null) {
            try {
               stream.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
         }

         if (output != null) {
            try {
               output.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
         }

      }

      return version;
   }

   private String getMappings() throws IOException {
      String version = this.getVersion();
      RequestConfig.Builder builder = RequestConfig.custom();
      builder.setConnectTimeout(180000);
      builder.setAuthenticationEnabled(true);
      builder.setConnectionRequestTimeout(180000);
      RequestConfig config = builder.build();
      String url = this.DataBase.getUrl().replace("/{schema}", "") + "/_mappings" + (Integer.parseInt(version.charAt(0) + "") >= 7 ? "?include_type_name=true" : "");
      HttpGet get = new HttpGet(url);
      get.setConfig(config);
      Auth auth = new BasicAuth(this.DataBase.getUsername(), this.DataBase.getPassword());
      get.setHeader(auth.getHeader());
      HttpClient client = HttpClientBuilder.create().build();
      InputStream stream = null;
      ByteArrayOutputStream output = null;

      String var15;
      try {
         HttpResponse response = client.execute(get);
         HttpEntity entity = response.getEntity();
         Header encoding = entity.getContentEncoding();
         String charset = encoding == null ? "UTF-8" : encoding.getValue();
         stream = entity.getContent();
         output = new ByteArrayOutputStream();
         int read = 0;

         while((read = stream.read()) != -1) {
            output.write(read);
         }

         output.flush();
         var15 = output.toString(charset);
      } catch (IOException e) {
         e.printStackTrace();
         throw e;
      } finally {
         if (stream != null) {
            try {
               stream.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
         }

         if (output != null) {
            try {
               output.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
         }

      }

      return var15;
   }

   public List<Schema> getSchema(Statement statement) throws SQLException {
      List<Schema> schemas = new ArrayList();
      Schema schema = new Schema("default");
      schemas.add(schema);
      return schemas;
   }

   public List<Table> getTable(Statement statement, String schema) throws SQLException {
      return null;
   }

   public List<Column> getColumn(Statement statement, String schema, String table) throws SQLException {
      return null;
   }

   public List<View> getView(Statement statement, String schema) throws SQLException {
      return null;
   }

   public List<String> getList(Statement statement, String schema) throws SQLException {
      return null;
   }

   public String getTableType(Statement statement, String tableName) throws SQLException {
      return null;
   }

   public static void main(String[] args) {
      DataBase db = new DataBase();
      db.setUsername("test1");
      db.setPassword("123456");
      db.setUrl("http://192.168.2.229:9200");
      CountDownLatch cdl = new CountDownLatch(1);
      CacheEs es = new CacheEs(db, cdl);
      es.run();

      for(Schema schema : db.getSchemaList()) {
         for(Table table : schema.getTableList()) {
            System.out.println("---------------------------------");
            System.out.println(schema.getName() + "\t->" + table.getName() + ":");

            for(Column column : table.getColumnList()) {
               System.out.print("\t");
               System.out.print(String.format("%100s", column.getColumnName()));
               System.out.println(String.format("%20s", column.getDataType()));
            }
         }
      }

   }

   class BasicAuth implements Auth {
      String user;
      String password;

      public BasicAuth(String user, String password) {
         this.user = user;
         this.password = password;
      }

      public Header getHeader() {
         StringBuilder sb = new StringBuilder();

         try {
            sb.append("Basic ");
            sb.append(Base64.getEncoder().encodeToString((this.user + ":" + this.password).getBytes("UTF-8")));
            return new BasicHeader("Authorization", sb.toString());
         } catch (Exception e) {
            e.printStackTrace();
            return new BasicHeader("Authorization", sb.toString());
         }
      }
   }

   interface Auth {
      Header getHeader();
   }
}
