package com.alibaba.druid.sql.ast;

import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.util.FnvHash;
import java.util.ArrayList;
import java.util.List;

public class SQLDataTypeImpl extends SQLObjectImpl implements SQLDataType, SQLDbTypedObject {
   private String name;
   private long nameHashCode64;
   protected final List<SQLExpr> arguments;
   private Boolean withTimeZone;
   private boolean withLocalTimeZone;
   private DbType dbType;
   private boolean unsigned;
   private boolean zerofill;
   private SQLExpr indexBy;

   public SQLDataTypeImpl() {
      this.arguments = new ArrayList();
      this.withLocalTimeZone = false;
   }

   public SQLDataTypeImpl(String name) {
      this.arguments = new ArrayList();
      this.withLocalTimeZone = false;
      this.name = name;
   }

   public SQLDataTypeImpl(String name, int precision) {
      this(name);
      this.addArgument(new SQLIntegerExpr(precision));
   }

   public SQLDataTypeImpl(String name, SQLExpr arg) {
      this(name);
      this.addArgument(arg);
   }

   public SQLDataTypeImpl(String name, int precision, int scale) {
      this(name);
      this.addArgument(new SQLIntegerExpr(precision));
      this.addArgument(new SQLIntegerExpr(scale));
   }

   protected void accept0(SQLASTVisitor visitor) {
      if (visitor.visit((SQLDataType)this)) {
         for(int i = 0; i < this.arguments.size(); ++i) {
            SQLExpr arg = (SQLExpr)this.arguments.get(i);
            if (arg != null) {
               arg.accept(visitor);
            }
         }
      }

      visitor.endVisit((SQLDataType)this);
   }

   public String getName() {
      return this.name;
   }

   public long nameHashCode64() {
      if (this.nameHashCode64 == 0L) {
         this.nameHashCode64 = FnvHash.hashCode64(this.name);
      }

      return this.nameHashCode64;
   }

   public void setName(String name) {
      this.name = name;
      this.nameHashCode64 = 0L;
   }

   public List<SQLExpr> getArguments() {
      return this.arguments;
   }

   public void addArgument(SQLExpr argument) {
      if (argument != null) {
         argument.setParent(this);
      }

      this.arguments.add(argument);
   }

   public boolean equals(Object o) {
      if (this == o) {
         return true;
      } else if (o != null && this.getClass() == o.getClass()) {
         SQLDataTypeImpl dataType = (SQLDataTypeImpl)o;
         if (this.name != null) {
            if (!this.name.equals(dataType.name)) {
               return false;
            }
         } else if (dataType.name != null) {
            return false;
         }

         if (!this.arguments.equals(dataType.arguments)) {
            return false;
         } else {
            return this.withTimeZone != null ? this.withTimeZone.equals(dataType.withTimeZone) : dataType.withTimeZone == null;
         }
      } else {
         return false;
      }
   }

   public int hashCode() {
      long value = this.nameHashCode64();
      return (int)(value ^ value >>> 32);
   }

   public Boolean getWithTimeZone() {
      return this.withTimeZone;
   }

   public void setWithTimeZone(Boolean withTimeZone) {
      this.withTimeZone = withTimeZone;
   }

   public boolean isWithLocalTimeZone() {
      return this.withLocalTimeZone;
   }

   public void setWithLocalTimeZone(boolean withLocalTimeZone) {
      this.withLocalTimeZone = withLocalTimeZone;
   }

   public DbType getDbType() {
      return this.dbType;
   }

   public int jdbcType() {
      long nameNash = this.nameHashCode64();
      if (nameNash == FnvHash.Constants.TINYINT) {
         return -6;
      } else if (nameNash == FnvHash.Constants.SMALLINT) {
         return 5;
      } else if (nameNash != FnvHash.Constants.INT && nameNash != FnvHash.Constants.INTEGER) {
         if (nameNash == FnvHash.Constants.BIGINT) {
            return -5;
         } else if (nameNash == FnvHash.Constants.DECIMAL) {
            return 3;
         } else if (nameNash == FnvHash.Constants.FLOAT) {
            return 6;
         } else if (nameNash == FnvHash.Constants.REAL) {
            return 7;
         } else if (nameNash == FnvHash.Constants.DOUBLE) {
            return 8;
         } else if (nameNash != FnvHash.Constants.NUMBER && nameNash != FnvHash.Constants.NUMERIC) {
            if (nameNash == FnvHash.Constants.BOOLEAN) {
               return 16;
            } else if (nameNash != FnvHash.Constants.DATE && nameNash != FnvHash.Constants.NEWDATE) {
               if (nameNash != FnvHash.Constants.DATETIME && nameNash != FnvHash.Constants.TIMESTAMP) {
                  if (nameNash == FnvHash.Constants.TIME) {
                     return 92;
                  } else if (nameNash == FnvHash.Constants.BLOB) {
                     return 2004;
                  } else if (nameNash == FnvHash.Constants.ROWID) {
                     return -8;
                  } else if (nameNash == FnvHash.Constants.REF) {
                     return 2006;
                  } else if (nameNash != FnvHash.Constants.TINYINT && nameNash != FnvHash.Constants.TINY) {
                     if (nameNash != FnvHash.Constants.SMALLINT && nameNash != FnvHash.Constants.SHORT) {
                        if (nameNash != FnvHash.Constants.INT && nameNash != FnvHash.Constants.INT24 && nameNash != FnvHash.Constants.INTEGER) {
                           if (nameNash != FnvHash.Constants.NUMBER && nameNash != FnvHash.Constants.NUMERIC) {
                              if (nameNash == FnvHash.Constants.BOOLEAN) {
                                 return 16;
                              } else if (nameNash != FnvHash.Constants.DATE && nameNash != FnvHash.Constants.YEAR && nameNash != FnvHash.Constants.NEWDATE) {
                                 if (nameNash != FnvHash.Constants.DATETIME && nameNash != FnvHash.Constants.TIMESTAMP) {
                                    if (nameNash == FnvHash.Constants.TIME) {
                                       return 92;
                                    } else if (nameNash == FnvHash.Constants.TINYBLOB) {
                                       return -3;
                                    } else if (nameNash == FnvHash.Constants.BLOB) {
                                       return 2004;
                                    } else if (nameNash == FnvHash.Constants.LONGBLOB) {
                                       return -4;
                                    } else if (nameNash == FnvHash.Constants.ROWID) {
                                       return -8;
                                    } else if (nameNash == FnvHash.Constants.REF) {
                                       return 2006;
                                    } else if (nameNash != FnvHash.Constants.BINARY && nameNash != FnvHash.Constants.GEOMETRY) {
                                       if (nameNash == FnvHash.Constants.SQLXML) {
                                          return 2009;
                                       } else if (nameNash == FnvHash.Constants.BIT) {
                                          return -7;
                                       } else if (nameNash == FnvHash.Constants.NCHAR) {
                                          return -15;
                                       } else if (nameNash != FnvHash.Constants.CHAR && nameNash != FnvHash.Constants.ENUM && nameNash != FnvHash.Constants.SET && nameNash != FnvHash.Constants.JSON) {
                                          if (nameNash != FnvHash.Constants.VARCHAR && nameNash != FnvHash.Constants.VARCHAR2 && nameNash != FnvHash.Constants.STRING) {
                                             if (nameNash != FnvHash.Constants.NVARCHAR && nameNash != FnvHash.Constants.NVARCHAR2) {
                                                if (nameNash != FnvHash.Constants.CLOB && nameNash != FnvHash.Constants.TEXT && nameNash != FnvHash.Constants.TINYTEXT && nameNash != FnvHash.Constants.MEDIUMTEXT && nameNash != FnvHash.Constants.LONGTEXT) {
                                                   if (nameNash == FnvHash.Constants.NCLOB) {
                                                      return 2011;
                                                   } else if (nameNash == FnvHash.Constants.TINYBLOB) {
                                                      return -3;
                                                   } else if (nameNash == FnvHash.Constants.LONGBLOB) {
                                                      return -4;
                                                   } else if (nameNash != FnvHash.Constants.BINARY && nameNash != FnvHash.Constants.GEOMETRY) {
                                                      if (nameNash == FnvHash.Constants.SQLXML) {
                                                         return 2009;
                                                      } else if (nameNash == FnvHash.Constants.NCHAR) {
                                                         return -15;
                                                      } else if (nameNash != FnvHash.Constants.CHAR && nameNash != FnvHash.Constants.JSON) {
                                                         if (nameNash != FnvHash.Constants.VARCHAR && nameNash != FnvHash.Constants.VARCHAR2 && nameNash != FnvHash.Constants.STRING) {
                                                            if (nameNash != FnvHash.Constants.NVARCHAR && nameNash != FnvHash.Constants.NVARCHAR2) {
                                                               if (nameNash != FnvHash.Constants.CLOB && nameNash != FnvHash.Constants.TEXT && nameNash != FnvHash.Constants.TINYTEXT && nameNash != FnvHash.Constants.MEDIUMTEXT && nameNash != FnvHash.Constants.LONGTEXT) {
                                                                  return nameNash == FnvHash.Constants.NCLOB ? 2011 : 0;
                                                               } else {
                                                                  return 2005;
                                                               }
                                                            } else {
                                                               return -9;
                                                            }
                                                         } else {
                                                            return 12;
                                                         }
                                                      } else {
                                                         return 1;
                                                      }
                                                   } else {
                                                      return -2;
                                                   }
                                                } else {
                                                   return 2005;
                                                }
                                             } else {
                                                return -9;
                                             }
                                          } else {
                                             return 12;
                                          }
                                       } else {
                                          return 1;
                                       }
                                    } else {
                                       return -2;
                                    }
                                 } else {
                                    return 93;
                                 }
                              } else {
                                 return 91;
                              }
                           } else {
                              return 2;
                           }
                        } else {
                           return 4;
                        }
                     } else {
                        return 5;
                     }
                  } else {
                     return -6;
                  }
               } else {
                  return 93;
               }
            } else {
               return 91;
            }
         } else {
            return 2;
         }
      } else {
         return 4;
      }
   }

   public void setDbType(DbType dbType) {
      this.dbType = dbType;
   }

   public SQLDataTypeImpl clone() {
      SQLDataTypeImpl x = new SQLDataTypeImpl();
      this.cloneTo(x);
      return x;
   }

   public void cloneTo(SQLDataTypeImpl x) {
      x.dbType = this.dbType;
      x.name = this.name;
      x.nameHashCode64 = this.nameHashCode64;

      for(SQLExpr arg : this.arguments) {
         x.addArgument(arg.clone());
      }

      x.withTimeZone = this.withTimeZone;
      x.withLocalTimeZone = this.withLocalTimeZone;
      x.zerofill = this.zerofill;
      x.unsigned = this.unsigned;
      if (this.indexBy != null) {
         x.setIndexBy(this.indexBy.clone());
      }

   }

   public String toString() {
      return SQLUtils.toSQLString(this, (DbType)this.dbType);
   }

   public boolean isUnsigned() {
      return this.unsigned;
   }

   public void setUnsigned(boolean unsigned) {
      this.unsigned = unsigned;
   }

   public boolean isZerofill() {
      return this.zerofill;
   }

   public void setZerofill(boolean zerofill) {
      this.zerofill = zerofill;
   }

   public SQLExpr getIndexBy() {
      return this.indexBy;
   }

   public void setIndexBy(SQLExpr x) {
      if (x != null) {
         x.setParent(this);
      }

      this.indexBy = x;
   }

   public boolean isInt() {
      long hashCode64 = this.nameHashCode64();
      return hashCode64 == FnvHash.Constants.BIGINT || hashCode64 == FnvHash.Constants.INT || hashCode64 == FnvHash.Constants.INT4 || hashCode64 == FnvHash.Constants.INT24 || hashCode64 == FnvHash.Constants.SMALLINT || hashCode64 == FnvHash.Constants.TINYINT || hashCode64 == FnvHash.Constants.INTEGER;
   }

   public boolean isNumberic() {
      long hashCode64 = this.nameHashCode64();
      return hashCode64 == FnvHash.Constants.REAL || hashCode64 == FnvHash.Constants.FLOAT || hashCode64 == FnvHash.Constants.DOUBLE || hashCode64 == FnvHash.Constants.DOUBLE_PRECISION || hashCode64 == FnvHash.Constants.NUMBER || hashCode64 == FnvHash.Constants.DECIMAL;
   }

   public boolean isString() {
      long hashCode64 = this.nameHashCode64();
      return hashCode64 == FnvHash.Constants.VARCHAR || hashCode64 == FnvHash.Constants.VARCHAR2 || hashCode64 == FnvHash.Constants.CHAR || hashCode64 == FnvHash.Constants.NCHAR || hashCode64 == FnvHash.Constants.NVARCHAR || hashCode64 == FnvHash.Constants.NVARCHAR2 || hashCode64 == FnvHash.Constants.TEXT || hashCode64 == FnvHash.Constants.TINYTEXT || hashCode64 == FnvHash.Constants.MEDIUMTEXT || hashCode64 == FnvHash.Constants.LONGTEXT || hashCode64 == FnvHash.Constants.CLOB || hashCode64 == FnvHash.Constants.NCLOB || hashCode64 == FnvHash.Constants.MULTIVALUE || hashCode64 == FnvHash.Constants.STRING;
   }

   public boolean hasKeyLength() {
      long hashCode64 = this.nameHashCode64();
      return hashCode64 == FnvHash.Constants.VARCHAR || hashCode64 == FnvHash.Constants.VARCHAR2 || hashCode64 == FnvHash.Constants.CHAR || hashCode64 == FnvHash.Constants.NCHAR || hashCode64 == FnvHash.Constants.NVARCHAR || hashCode64 == FnvHash.Constants.NVARCHAR2 || hashCode64 == FnvHash.Constants.TEXT || hashCode64 == FnvHash.Constants.TINYTEXT || hashCode64 == FnvHash.Constants.MEDIUMTEXT || hashCode64 == FnvHash.Constants.LONGTEXT || hashCode64 == FnvHash.Constants.CLOB || hashCode64 == FnvHash.Constants.NCLOB || hashCode64 == FnvHash.Constants.MULTIVALUE || hashCode64 == FnvHash.Constants.STRING || hashCode64 == FnvHash.Constants.BLOB || hashCode64 == FnvHash.Constants.TINYBLOB || hashCode64 == FnvHash.Constants.LONGBLOB || hashCode64 == FnvHash.Constants.BINARY || hashCode64 == FnvHash.Constants.VARBINARY;
   }
}
