package com.chenyang.nse.bussiness.bean;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class DBEasyCache {
   public final DataBase dataBase;
   private final Map<String, Schema> schemas;
   private final Map<String, Map<String, Table>> schemaTables;
   private final Map<String, Map<String, Column>> tableColumns;
   private boolean ignoreCase;

   public DBEasyCache(DataBase dataBase) {
      this.ignoreCase = false;
      this.dataBase = dataBase;
      this.schemas = new HashMap();
      this.schemaTables = new HashMap();
      this.tableColumns = new HashMap();
   }

   public DBEasyCache(DataBase dataBase, boolean ignoreCase) {
      this(dataBase);
      this.ignoreCase = ignoreCase;
   }

   public void init() {
      if (this.dataBase.getSchemaList() != null) {
         for(Schema schema : this.dataBase.getSchemaList()) {
            if (schema != null && schema.getName() != null && schema.getName().length() != 0) {
               String schemaId = this.getId(schema.getName());
               this.schemas.put(schemaId, schema);
               this.schemaTables.putIfAbsent(schemaId, new HashMap());
               if (schema.getTableList() != null && schema.getTableList().size() > 0) {
                  Map<String, Table> tableMap = (Map)this.schemaTables.get(schemaId);

                  for(Table table : schema.getTableList()) {
                     if (table != null && table.getName() != null && table.getName().length() != 0) {
                        tableMap.put(this.getId(table.getName()), table);
                        String tableId = this.getId(schema.getName(), table.getName());
                        this.tableColumns.putIfAbsent(tableId, new HashMap());
                        if (table.getColumnList() != null && table.getColumnList().size() > 0) {
                           Map<String, Column> columnMap = (Map)this.tableColumns.get(tableId);

                           for(Column column : table.getColumnList()) {
                              if (column != null && column.getColumnName() != null && column.getColumnName().length() != 0) {
                                 columnMap.put(this.getId(column.getColumnName()), column);
                              }
                           }
                        }
                     }
                  }
               }
            }
         }
      }

   }

   public List<Schema> getSchemas() {
      return (List<Schema>)(this.dataBase.getSchemaList() == null ? new ArrayList() : (List)this.dataBase.getSchemaList().stream().filter((x) -> x != null && x.getName() != null && x.getName().length() > 0).collect(Collectors.toList()));
   }

   public List<Table> getTables() {
      return (List)this.dataBase.getSchemaList().stream().filter((x) -> x != null && x.getName() != null && x.getName().length() > 0 && x.getTableList() != null && x.getTableList().size() > 0).flatMap((x) -> x.getTableList().stream()).filter((x) -> x != null && x.getName() != null && x.getName().length() > 0).collect(Collectors.toList());
   }

   public List<Column> getColumns() {
      return (List)this.dataBase.getSchemaList().stream().filter((x) -> x != null && x.getName() != null && x.getName().length() > 0 && x.getTableList() != null && x.getTableList().size() > 0).flatMap((x) -> x.getTableList().stream()).filter((x) -> x != null && x.getName() != null && x.getName().length() > 0 && x.getColumnList() != null && x.getColumnList().size() > 0).flatMap((x) -> x.getColumnList().stream()).filter((x) -> x != null && x.getColumnName() != null && x.getColumnName().length() > 0).collect(Collectors.toList());
   }

   public Schema getSchema(String schemaName) {
      return schemaName != null && schemaName.length() != 0 ? (Schema)this.schemas.get(this.getId(schemaName)) : null;
   }

   public List<Table> getSchemaTables(String schemaName) {
      if (schemaName != null && schemaName.length() != 0) {
         String id = this.getId(schemaName);
         Schema schema = (Schema)this.schemas.get(id);
         return (List<Table>)(schema != null && schema.getTableList() != null ? schema.getTableList() : new ArrayList());
      } else {
         return new ArrayList();
      }
   }

   public Map<String, Table> getSchemaTableMap(String schemaName) {
      if (schemaName != null && schemaName.length() != 0) {
         String id = this.getId(schemaName);
         return (Map)this.schemaTables.getOrDefault(id, new HashMap());
      } else {
         return new HashMap();
      }
   }

   public List<Column> getSchemaColumns(String schemaName) {
      if (schemaName != null && schemaName.length() != 0) {
         List<Table> tables = this.getSchemaTables(schemaName);
         return (List<Column>)(tables != null && tables.size() != 0 ? (List)tables.stream().filter((x) -> x != null && x.getColumnList() != null && x.getColumnList().size() > 0).flatMap((x) -> x.getColumnList().stream()).collect(Collectors.toList()) : new ArrayList());
      } else {
         return new ArrayList();
      }
   }

   public Table getTable(String schemaName, String tableName) {
      if (schemaName != null && schemaName.length() != 0 && tableName != null && tableName.length() != 0) {
         String schemaId = this.getId(schemaName);
         Map<String, Table> tableMap = (Map)this.schemaTables.get(schemaId);
         return tableMap != null && tableMap.size() != 0 ? (Table)tableMap.get(this.getId(tableName)) : null;
      } else {
         return null;
      }
   }

   public List<Column> getTableColumns(String schemaName, String tableName) {
      if (schemaName != null && schemaName.length() != 0 && tableName != null && tableName.length() != 0) {
         Table table = this.getTable(schemaName, tableName);
         if (table == null) {
            return new ArrayList();
         } else {
            return (List<Column>)(table.getColumnList() == null ? new ArrayList() : table.getColumnList());
         }
      } else {
         return new ArrayList();
      }
   }

   public Map<String, Column> getTableColumnMap(String schemaName, String tableName) {
      if (schemaName != null && schemaName.length() != 0 && tableName != null && tableName.length() != 0) {
         String id = this.getId(schemaName, tableName);
         return (Map)this.tableColumns.getOrDefault(id, new HashMap());
      } else {
         return new HashMap();
      }
   }

   public Column getColumn(String schemaName, String tableName, String columnName) {
      if (schemaName != null && schemaName.length() != 0 && tableName != null && tableName.length() != 0 && columnName != null && columnName.length() != 0) {
         Map<String, Column> columnMap = this.getTableColumnMap(schemaName, tableName);
         return columnMap != null && columnMap.size() != 0 ? (Column)columnMap.get(this.getId(columnName)) : null;
      } else {
         return null;
      }
   }

   private String getId(String... ids) {
      return !this.ignoreCase ? String.join("$->", (Iterable)Arrays.stream(ids).map((x) -> x.toLowerCase()).collect(Collectors.toList())) : String.join("$->", ids);
   }
}
