package util.getdata;

import bean.Column;
import bean.DataBase;
import bean.Schema;
import bean.Synonym;
import bean.Table;
import bean.View;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import util.JdbcCacheUtil;
import util.StringJoin;

public class CacheOracle extends CacheData {
   public static final int QUERY_SCHEMA_NUMS = 10;
   public static final int QUERY_TABLE_NUMS = 300;
   public ExecutorService threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

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

   public void run() {
      System.out.println("oracle开始缓存");
      long startTime = System.currentTimeMillis();
      boolean var13 = false;

      label101: {
         try {
            var13 = true;
            this.cacheWriteToRedis();
            var13 = false;
            break label101;
         } catch (Exception e) {
            e.printStackTrace();
            var13 = false;
         } finally {
            if (var13) {
               try {
                  JdbcCacheUtil.closeConnection(this.connection);
                  if (this.statement != null) {
                     this.statement.close();
                  }
               } catch (Exception throwables) {
                  throwables.printStackTrace();
               }

               this.getCdl().countDown();
               System.out.println("oracle结束缓存");
               long endTime = System.currentTimeMillis();
               System.out.println("共用时：" + (endTime - startTime) + "毫秒");
            }
         }

         try {
            JdbcCacheUtil.closeConnection(this.connection);
            if (this.statement != null) {
               this.statement.close();
            }
         } catch (Exception throwables) {
            throwables.printStackTrace();
         }

         this.getCdl().countDown();
         System.out.println("oracle结束缓存");
         long endTime = System.currentTimeMillis();
         System.out.println("共用时：" + (endTime - startTime) + "毫秒");
         return;
      }

      try {
         JdbcCacheUtil.closeConnection(this.connection);
         if (this.statement != null) {
            this.statement.close();
         }
      } catch (Exception throwables) {
         throwables.printStackTrace();
      }

      this.getCdl().countDown();
      System.out.println("oracle结束缓存");
      long endTime = System.currentTimeMillis();
      System.out.println("共用时：" + (endTime - startTime) + "毫秒");
   }

   public List<Schema> cacheToMemory() throws SQLException, ClassNotFoundException {
      this.connection = JdbcCacheUtil.getConnection(this.DataBase.getUrl(), this.DataBase.getUsername(), this.DataBase.getPassword());
      this.statement = this.connection.createStatement();
      List<Schema> schemaList = this.getSchema(this.statement, this.DataBase);
      List<Table> tableList = new ArrayList();
      List<View> viewList = new ArrayList();
      List<Synonym> synonymList = new ArrayList();
      List<Column> columnList = new ArrayList();
      this.getTablesByShared(this.connection, this.statement, schemaList, tableList, columnList);
      this.getViewsByShared(this.connection, this.statement, schemaList, viewList);
      this.getSynonymsByShared(this.connection, this.statement, schemaList, synonymList);
      Map<String, List<Column>> columnMap = new HashMap();

      for(int i = 0; i < columnList.size(); ++i) {
         if (columnList.get(i) != null) {
            String key = ((Column)columnList.get(i)).getSchema() + "." + ((Column)columnList.get(i)).getTable();
            if (!columnMap.containsKey(key)) {
               columnMap.put(key, new ArrayList());
            }

            ((List)columnMap.get(key)).add(columnList.get(i));
         }
      }

      for(Schema schema : schemaList) {
         List<Table> tables = new ArrayList();

         for(int i = 0; i < tableList.size(); ++i) {
            Table table = (Table)tableList.get(i);
            if (table.getSchema().equals(schema.getName())) {
               tables.add(table);
            }
         }

         schema.setTableList(tables);

         for(Table table : schema.getTableList()) {
            table.setColumnList((List)columnMap.get(schema.getName() + "." + table.getName()));
         }

         List<View> views = new ArrayList();

         for(int i = 0; i < viewList.size(); ++i) {
            View view = (View)viewList.get(i);
            if (view.getSchema().equals(schema.getName())) {
               views.add(view);
            }
         }

         schema.setViewList(views);
         List<Synonym> synonyms = new ArrayList();

         for(int i = 0; i < synonymList.size(); ++i) {
            Synonym synonym = (Synonym)synonymList.get(i);
            if (synonym.getSchema().equals(schema.getName())) {
               synonyms.add(synonym);
            }
         }

         schema.setSynonymList(synonyms);
      }

      return schemaList;
   }

   public void toUppercase(List<Schema> schemaList) {
      for(int i = 0; i < schemaList.size(); ++i) {
         Schema schema = (Schema)schemaList.get(i);
         List<Table> tableList = schema.getTableList();

         for(int i1 = 0; i1 < tableList.size(); ++i1) {
            Table table = (Table)tableList.get(i1);
            if (table.getColumnList() != null) {
               List<Column> columnList = table.getColumnList();

               for(int i2 = 0; i2 < columnList.size(); ++i2) {
                  Column column = (Column)columnList.get(i2);
                  if (column != null && !this.isEmpty(column.getColumnName())) {
                     column.setColumnName(column.getColumnName());
                  }
               }

               if (!this.isEmpty(table.getName())) {
                  table.setName(table.getName());
               }
            }
         }

         List<View> viewList = schema.getViewList();

         for(int i1 = 0; i1 < viewList.size(); ++i1) {
            View view = (View)viewList.get(i1);
            if (view != null && !this.isEmpty(view.getName())) {
               view.setName(view.getName());
            }
         }

         if (!this.isEmpty(schema.getName())) {
            schema.setName(schema.getName());
         }
      }

   }

   private boolean isEmpty(String str) {
      return str == null || str.length() == 0;
   }

   public List<Schema> getSchema(Statement statement, DataBase dataBase) throws SQLException {
      List<Schema> schemaList = new ArrayList();
      String sql = "SELECT USERNAME FROM all_users";
      ResultSet resultSet = statement.executeQuery(sql);

      while(resultSet.next()) {
         String schemaName = resultSet.getString("USERNAME");
         Schema schema = new Schema(schemaName);
         if (!dataBase.getExcludeSchema().contains(schemaName)) {
            schema.setRealName(schemaName);
            schemaList.add(schema);
         }
      }

      resultSet.close();
      return schemaList;
   }

   public List<Schema> getSchema(Statement statement) throws SQLException {
      List<Schema> schemaList = new ArrayList();
      String sql = "SELECT USERNAME FROM all_users WHERE ACCOUNT_STATUS  = 'OPEN'";
      ResultSet resultSet = statement.executeQuery(sql);

      while(resultSet.next()) {
         Schema schema = new Schema(resultSet.getString("USERNAME"));
         schema.setRealName(resultSet.getString("USERNAME"));
         schemaList.add(schema);
      }

      resultSet.close();
      return schemaList;
   }

   public List<Table> getTable(Statement statement, String schema) throws SQLException {
      List<Table> tableList = new ArrayList();
      String sql = "select TABLE_NAME from all_tables WHERE OWNER  = '" + schema + "'";
      ResultSet resultSet = statement.executeQuery(sql);

      while(resultSet.next()) {
         Table table = new Table(resultSet.getString("TABLE_NAME"), schema);
         table.setRealName(resultSet.getString("TABLE_NAME"));
         tableList.add(table);
      }

      resultSet.close();
      return tableList;
   }

   public List<Table> getTables(Statement statement, List<Schema> schemas) throws SQLException {
      List<Table> tableList = new ArrayList();
      List<String> schemaNames = new ArrayList();

      for(int i = 0; i < schemas.size(); ++i) {
         Schema schema = (Schema)schemas.get(i);
         if (schema != null && schema.getName().length() > 0) {
            schemaNames.add(schema.getName());
         }
      }

      String schemasWhere = StringJoin.join(schemaNames, "','");
      String sql = "select OWNER,TABLE_NAME from all_tables WHERE OWNER  IN  ('" + schemasWhere + "')";
      ResultSet resultSet = statement.executeQuery(sql);

      while(resultSet.next()) {
         Table table = new Table(resultSet.getString("TABLE_NAME"), resultSet.getString("OWNER"));
         table.setRealName(resultSet.getString("TABLE_NAME"));
         tableList.add(table);
      }

      resultSet.close();
      return tableList;
   }

   public List<View> getViews(Statement statement, List<Schema> schemas) throws SQLException {
      List<View> views = new ArrayList();
      List<String> schemaNames = new ArrayList();

      for(int i = 0; i < schemas.size(); ++i) {
         Schema schema = (Schema)schemas.get(i);
         if (schema != null && schema.getName().length() > 0) {
            schemaNames.add(schema.getName());
         }
      }

      String schemasWhere = StringJoin.join(schemaNames, "','");
      String sql = "select OWNER, VIEW_NAME ,TEXT from all_VIEWS where OWNER IN ( '" + schemasWhere + "')";
      ResultSet resultSet = statement.executeQuery(sql);

      while(resultSet.next()) {
         View view = new View(resultSet.getString("OWNER"), resultSet.getString("VIEW_NAME"), resultSet.getString("TEXT"));
         views.add(view);
      }

      resultSet.close();
      return views;
   }

   public List<Synonym> getSynonyms(Statement statement, List<Schema> schemas) throws SQLException {
      List<Synonym> synonyms = new ArrayList();
      List<String> schemaNames = new ArrayList();

      for(int i = 0; i < schemas.size(); ++i) {
         Schema schema = (Schema)schemas.get(i);
         if (schema != null && schema.getName().length() > 0) {
            schemaNames.add(schema.getName());
         }
      }

      String schemasWhere = StringJoin.join(schemaNames, "','");
      String sql = "SELECT OWNER,TABLE_OWNER,TABLE_NAME,SYNONYM_NAME FROM all_SYNONYMS WHERE OWNER in ('" + schemasWhere + "')";
      ResultSet resultSet = statement.executeQuery(sql);

      while(resultSet.next()) {
         Synonym view = new Synonym(resultSet.getString("OWNER"), resultSet.getString("TABLE_NAME"), resultSet.getString("SYNONYM_NAME"));
         view.setTableOwner(resultSet.getString("TABLE_OWNER"));
         synonyms.add(view);
      }

      resultSet.close();
      return synonyms;
   }

   public void getTablesByShared(Connection connection, Statement statement, List<Schema> schemas, List<Table> tableList, List<Column> columnList) throws SQLException {
      List<Table> tablesShared;
      for(int schemaIndex = 0; schemaIndex < schemas.size(); tableList.addAll(tablesShared)) {
         List<Schema> tempSchemas = new ArrayList();
         int loopSize = 10 > schemas.size() - schemaIndex ? schemas.size() - schemaIndex : 10;

         for(int i = 0; i < loopSize; ++i) {
            tempSchemas.add(schemas.get(schemaIndex++));
         }

         tablesShared = this.getTables(statement, tempSchemas);
         if (tablesShared.size() > 0) {
            this.getColumnsByShared(connection, tempSchemas, tablesShared, columnList);
         }
      }

   }

   public void getViewsByShared(Connection connection, Statement statement, List<Schema> schemas, List<View> views) throws SQLException {
      int schemaIndex = 0;

      while(schemaIndex < schemas.size()) {
         List<Schema> tempSchemas = new ArrayList();
         int loopSize = 10 > schemas.size() - schemaIndex ? schemas.size() - schemaIndex : 10;

         for(int i = 0; i < loopSize; ++i) {
            tempSchemas.add(schemas.get(schemaIndex++));
         }

         List<View> viewsShared = this.getViews(statement, tempSchemas);
         views.addAll(viewsShared);
      }

   }

   public void getSynonymsByShared(Connection connection, Statement statement, List<Schema> schemas, List<Synonym> synonyms) throws SQLException {
      int schemaIndex = 0;

      while(schemaIndex < schemas.size()) {
         List<Schema> tempSchemas = new ArrayList();
         int loopSize = 10 > schemas.size() - schemaIndex ? schemas.size() - schemaIndex : 10;

         for(int i = 0; i < loopSize; ++i) {
            tempSchemas.add(schemas.get(schemaIndex++));
         }

         List<Synonym> synonymsShared = this.getSynonyms(statement, tempSchemas);
         synonyms.addAll(synonymsShared);
      }

   }

   public void getColumnsByShared(Connection connection, List<Schema> schemas, List<Table> tables, List<Column> columnList) throws SQLException {
      try {
         int tableIndex = 0;
         CountDownLatch cdl = new CountDownLatch(1);
         System.out.println("cdl数量为" + (tables.size() / 300 + 1));

         while(tableIndex < tables.size()) {
            List<Table> tempTables = new ArrayList();
            if (300 > tables.size() - tableIndex) {
               int var10000 = tables.size() - tableIndex;
            } else {
               boolean var12 = true;
            }

            for(int i = 0; i < tables.size(); ++i) {
               tempTables.add(tables.get(tableIndex++));
            }

            ColumnThreads columnThreads = new ColumnThreads(connection, schemas, tempTables, columnList, cdl);
            this.threadPool.execute(columnThreads);
         }

         cdl.await();
      } catch (InterruptedException e) {
         e.printStackTrace();
      }

   }

   public List<Column> getColumn(Statement statement, String schema, String table) throws SQLException {
      List<Column> columnList = new ArrayList();
      String sql = "SELECT OWNER,COLUMN_NAME,DATA_TYPE FROM  all_tab_columns WHERE TABLE_NAME  = '" + table + "' and OWNER  = '" + schema + "'";
      ResultSet resultSet = statement.executeQuery(sql);

      while(resultSet.next()) {
         columnList.add(new Column(resultSet.getString("COLUMN_NAME"), schema, table, resultSet.getString("DATA_TYPE")));
      }

      resultSet.close();
      return columnList;
   }

   public List<Column> getColumns(Statement statement, List<Schema> schemas, List<Table> tables) throws SQLException {
      List<String> schemaNames = new ArrayList();

      for(int i = 0; i < schemas.size(); ++i) {
         Schema schema = (Schema)schemas.get(i);
         if (schema != null && schema.getName().length() > 0) {
            schemaNames.add(schema.getName());
         }
      }

      String schemasWhere = StringJoin.join(schemaNames, "','");
      List<String> tableNames = new ArrayList();

      for(int i = 0; i < tables.size(); ++i) {
         Table table = (Table)tables.get(i);
         if (table != null && table.getName().length() > 0) {
            tableNames.add(table.getName());
         }
      }

      String tablesWhere = StringJoin.join(tableNames, "','");
      List<Column> columnList = new ArrayList();
      String sql = "SELECT K.COLUMN_NAME,K.OWNER,K.TABLE_NAME,K.DATA_TYPE,NVL(C.PK,0) PK FROM  all_tab_columns K\nLEFT JOIN (\nSELECT A.OWNER ,A.TABLE_NAME, B.COLUMN_NAME,1 AS PK FROM SYS.ALL_CONSTRAINTS A  \nLEFT JOIN ALL_CONS_COLUMNS B ON A.OWNER=B.OWNER AND A.CONSTRAINT_NAME=B.CONSTRAINT_NAME  AND A.TABLE_NAME=B.TABLE_NAME \nWHERE A.TABLE_NAME  ='AT_TEST' AND A.CONSTRAINT_TYPE ='P'\n) C ON K.OWNER=C.OWNER AND K.TABLE_NAME=C.TABLE_NAME AND K.COLUMN_NAME=C.COLUMN_NAME\nWHERE K.TABLE_NAME in ('" + tablesWhere + "') and K.OWNER  in( '" + schemasWhere + "') ";
      ResultSet resultSet = statement.executeQuery(sql);

      while(resultSet.next()) {
         Column column = new Column(resultSet.getString("COLUMN_NAME"), resultSet.getString("OWNER"), resultSet.getString("TABLE_NAME"), resultSet.getString("DATA_TYPE"));
         column.setPk(resultSet.getInt("PK"));
         columnList.add(column);
      }

      resultSet.close();
      return columnList;
   }

   public List<View> getView(Statement statement, String schema) throws SQLException {
      List<View> views = new ArrayList();
      String sql = "select VIEW_NAME ,TEXT from all_VIEWS where OWNER = '" + schema + "'";
      ResultSet resultSet = statement.executeQuery(sql);

      while(resultSet.next()) {
         String table_name = resultSet.getString("VIEW_NAME");
         String view_definition = resultSet.getString("TEXT").replaceAll("`", "");
         views.add(new View(table_name, view_definition));
      }

      resultSet.close();
      return views;
   }

   public List<Synonym> getSynonym(Statement statement, String schema) throws SQLException {
      List<Synonym> synonyms = new ArrayList();
      String sql = "SELECT SYNONYM_NAME , TABLE_NAME FROM all_SYNONYMS WHERE TABLE_OWNER = '" + schema + "'";
      ResultSet resultSet = statement.executeQuery(sql);

      while(resultSet.next()) {
         String SYNONYM_NAME = resultSet.getString("SYNONYM_NAME");
         String TABLE_NAME = resultSet.getString("TABLE_NAME");
         synonyms.add(new Synonym(SYNONYM_NAME, TABLE_NAME));
      }

      resultSet.close();
      return synonyms;
   }
}
