package util.sqlparse.visitor.kingbase;

import bean.Column;
import bean.Schema;
import bean.Table;
import bean.View;
import com.chenyang.druid.util.StringUtils;
import java.util.Locale;
import java.util.Map;
import util.getdata.DatabaseCache;
import util.sqlparse.visitor.common.names.NameWrapper;

public class KingbaseNameWrapper extends NameWrapper {
   public static final String PLACE_HOLDER = "\"";

   public KingbaseNameWrapper(DatabaseCache cache) {
      super(cache);
   }

   public String unwrapSchema(String schema) {
      if (schema != null && schema.length() != 0) {
         if (this.isCaseSensitive && schema.startsWith("\"")) {
            return this.raw(schema);
         } else {
            Schema sch = this.getSchema(schema);
            return sch != null ? sch.getName() : this.unwrapName(schema);
         }
      } else {
         return schema;
      }
   }

   public String unwrapTable(String schema, String table) {
      if (schema != null && schema.length() != 0) {
         if (table != null && table.length() != 0) {
            if (this.isCaseSensitive && table.startsWith("\"")) {
               return this.raw(table);
            } else {
               Table tb = this.getTable(schema, table);
               return tb != null ? tb.getName() : this.unwrapName(table);
            }
         } else {
            return table;
         }
      } else {
         return this.raw(table);
      }
   }

   public String unwrapFullColumn(Column c) {
      if (c == null) {
         return null;
      } else {
         String column = c.getColumnName();
         if (column != null && column.length() != 0) {
            ColInfo colInfo = this.getColumnInfo(c);
            this.unwrapColumn(colInfo);
            return colInfo.unwrap("\"");
         } else {
            return column;
         }
      }
   }

   private Schema getSchema(String schema) {
      if (schema != null && schema.length() != 0) {
         if (this.cache.getDataBase().isRedis()) {
            return this.getSchemaFromRedis(schema, this.isSensitive(schema));
         } else {
            Map<String, Schema> schemas = this.cache.getSchemas();
            if (this.isSensitive(schema)) {
               schema = this.raw(schema);
               return (Schema)schemas.get(schema);
            } else {
               schema = schema.trim();
               schema = this.unwrapName(schema);
               Schema sch = (Schema)schemas.get(schema);
               if (sch != null) {
                  return sch;
               } else {
                  for(Map.Entry<String, Schema> pair : schemas.entrySet()) {
                     if (((String)pair.getKey()).equalsIgnoreCase(schema)) {
                        return (Schema)pair.getValue();
                     }
                  }

                  return null;
               }
            }
         }
      } else {
         return null;
      }
   }

   public Table getTable(String schema, String table) {
      Schema sch = this.getSchema(schema);
      return sch == null ? null : this.getTable(sch, table);
   }

   private Table getTable(Schema sch, String table) {
      if (sch == null) {
         return null;
      } else if (this.cache.getDataBase().isRedis()) {
         return this.getTableFromRedis(sch, table, this.isSensitive(table));
      } else {
         table = table.trim();
         Map<String, Table> tables = this.cache.getTables();
         if (this.isSensitive(table)) {
            table = this.unwrapName(table);
            String id = this.cache.getSchemaTableId(sch.getName(), table);
            return (Table)tables.get(id);
         } else {
            table = this.unwrapName(table);
            String id = this.cache.getSchemaTableId(sch.getName(), table);
            Table tb = (Table)tables.get(id);
            if (tb != null) {
               return tb;
            } else {
               for(Map.Entry<String, Table> pair : tables.entrySet()) {
                  if (((String)pair.getKey()).equalsIgnoreCase(id)) {
                     return (Table)pair.getValue();
                  }
               }

               return null;
            }
         }
      }
   }

   private boolean isSensitive(String symbol) {
      return symbol.startsWith("\"") && this.isCaseSensitive;
   }

   public View getView(String schema, String viewName) {
      Schema sch = this.getSchema(schema);
      return sch == null ? null : this.getView(sch, viewName);
   }

   public View getView(Schema sch, String viewName) {
      if (sch == null) {
         return null;
      } else {
         return this.cache.getDataBase().isRedis() ? this.getViewFromRedis(sch, viewName, this.isSensitive(viewName)) : null;
      }
   }

   private void unwrapColumn(ColInfo colInfo) {
      String schema = colInfo.schema;
      String table = colInfo.table;
      String col = colInfo.column;
      if (colInfo.isValid()) {
         Schema sch = this.getSchema(schema);
         if (sch != null) {
            colInfo.schema = sch.getName();
         }

         Table tb = this.getTable(sch, table);
         if (tb != null) {
            colInfo.table = tb.getName();
         }

         if (tb != null && tb.getColumnList() != null && tb.getColumnList().size() > 0) {
            col = col.trim();
            boolean isCase = col.startsWith("\"");
            col = this.raw(col);

            for(Column column : tb.getColumnList()) {
               if (!this.isCaseSensitive) {
                  if (column.getColumnName().equalsIgnoreCase(col)) {
                     colInfo.column = column.getColumnName();
                     break;
                  }
               } else if (isCase) {
                  if (column.getColumnName().equals(col)) {
                     colInfo.column = column.getColumnName();
                     break;
                  }
               } else if (column.getColumnName().equalsIgnoreCase(col)) {
                  colInfo.column = column.getColumnName();
                  break;
               }
            }
         }

      }
   }

   protected String unwrapName(String name) {
      return name != null && name.length() != 0 ? name.replaceAll("\"", "") : name;
   }

   private String wrapName(String name) {
      return name != null && name.length() != 0 ? "\"" + name + "\"" : name;
   }

   public String wrapTable(String schema, String table) {
      if (schema != null && schema.length() != 0) {
         if (table != null && table.length() != 0) {
            return this.isCaseSensitive && !table.startsWith("\"") ? this.wrapName(table) : table;
         } else {
            return table;
         }
      } else {
         return table;
      }
   }

   public String wrapColumn(String Column) {
      if (Column != null && Column.length() != 0) {
         return this.isCaseSensitive && !Column.startsWith("\"") ? this.wrapName(Column) : Column;
      } else {
         return Column;
      }
   }

   public static String normalize(String str, boolean isCaseSensitive) {
      if (StringUtils.isEmpty(str)) {
         return str;
      } else if (str.startsWith("\"")) {
         String trim = str.replaceAll("\"", "").trim();
         return !isCaseSensitive ? trim.toLowerCase(Locale.ROOT) : trim;
      } else {
         return str.toLowerCase(Locale.ROOT).trim();
      }
   }

   private String raw(String name) {
      if (name != null && name.length() != 0) {
         String nameRaw = this.unwrapName(name);
         return this.isCaseSensitive && nameRaw.toUpperCase().equals(name) ? nameRaw.toLowerCase() : nameRaw;
      } else {
         return name;
      }
   }
}
