package util.sqlparse.visitor.mysql;

import bean.Column;
import bean.Schema;
import bean.Table;
import bean.View;
import java.util.Map;
import util.getdata.DatabaseCache;
import util.sqlparse.visitor.common.names.NameWrapper;

public class MySQLNameWrapper extends NameWrapper {
   public static final String PLACE_HOLDER = "`";

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

   public String unwrapSchema(String schema) {
      if (schema != null && schema.length() != 0) {
         if (this.isCaseSensitive && schema.startsWith("`")) {
            return this.unwrapName(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.unwrapName(table);
            } else {
               Table tb = this.getTable(schema, table);
               return tb != null ? tb.getName() : this.unwrapName(table);
            }
         } else {
            return table;
         }
      } else {
         return this.unwrapName(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()) {
            Map<String, Schema> schemas = this.cache.getSchemas();
            if (this.isCaseSensitive) {
               schema = this.unwrapName(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 this.getSchemaFromRedis(schema, this.isCaseSensitive);
         }
      } 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()) {
         table = table.trim();
         Map<String, Table> tables = this.cache.getTables();
         if (this.isCaseSensitive) {
            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;
            }
         }
      } else {
         return this.getTableFromRedis(sch, table, 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 {
         viewName = this.unwrapName(viewName);
         if (this.cache.getDataBase().isRedis()) {
            return this.getViewFromRedis(sch, viewName, this.isCaseSensitive);
         } else {
            if (sch.getViewList() != null) {
               for(View view : sch.getViewList()) {
                  if (this.isCaseSensitive) {
                     if (view.getName().equals(viewName)) {
                        return view;
                     }
                  } else if (view.getName().equalsIgnoreCase(viewName)) {
                     return view;
                  }
               }
            }

            return 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.unwrapName(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;
   }
}
