package util.sqlparse.visitor.sqlserver;

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 SQLServerNameWrapper extends NameWrapper {
   public static final String PLACE_HOLDER = "\\[\\]";
   public static final String PLACE_HODLER_START = "[";

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

   public String unwrapSchema(String schema) {
      if (schema != null && schema.length() != 0) {
         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) {
            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()) {
            return this.getSchemaFromRedis(schema, false);
         } else {
            Map<String, Schema> schemas = this.cache.getSchemas();
            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, false);
      } else {
         table = table.trim();
         Map<String, Table> tables = this.cache.getTables();
         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;
         }
      }
   }

   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, false) : 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();
            col = this.unwrapName(col);

            for(Column column : tb.getColumnList()) {
               if (column.getColumnName().equalsIgnoreCase(col)) {
                  colInfo.column = column.getColumnName();
                  break;
               }
            }
         }

      }
   }

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