package com.chenyang.druid.sql.ast;

import com.chenyang.druid.DbType;
import com.chenyang.druid.sql.visitor.SQLASTVisitor;
import com.chenyang.druid.util.FnvHash;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class SQLStructDataType extends SQLObjectImpl implements SQLDataType {
   private DbType dbType;
   private List<Field> fields = new ArrayList();

   public SQLStructDataType() {
   }

   public SQLStructDataType(DbType dbType) {
      this.dbType = dbType;
   }

   public String getName() {
      return "STRUCT";
   }

   public long nameHashCode64() {
      return FnvHash.Constants.STRUCT;
   }

   public void setName(String name) {
      throw new UnsupportedOperationException();
   }

   public List<SQLExpr> getArguments() {
      return Collections.emptyList();
   }

   public Boolean getWithTimeZone() {
      return null;
   }

   public void setWithTimeZone(Boolean value) {
      throw new UnsupportedOperationException();
   }

   public boolean isWithLocalTimeZone() {
      return false;
   }

   public void setWithLocalTimeZone(boolean value) {
      throw new UnsupportedOperationException();
   }

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

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

   protected void accept0(SQLASTVisitor visitor) {
      if (visitor.visit(this)) {
         this.acceptChild(visitor, this.fields);
      }

      visitor.endVisit(this);
   }

   public SQLStructDataType clone() {
      SQLStructDataType x = new SQLStructDataType(this.dbType);

      for(Field field : this.fields) {
         x.addField(field.name, field.dataType.clone());
      }

      return x;
   }

   public List<Field> getFields() {
      return this.fields;
   }

   public Field addField(SQLName name, SQLDataType dataType) {
      Field field = new Field(name, dataType);
      field.setParent(this);
      this.fields.add(field);
      return field;
   }

   public int jdbcType() {
      return 2002;
   }

   public boolean isInt() {
      return false;
   }

   public boolean isNumberic() {
      return false;
   }

   public boolean isString() {
      return false;
   }

   public boolean hasKeyLength() {
      return false;
   }

   public static class Field extends SQLObjectImpl {
      private SQLName name;
      private SQLDataType dataType;
      private String comment;

      public Field(SQLName name, SQLDataType dataType) {
         this.setName(name);
         this.setDataType(dataType);
      }

      protected void accept0(SQLASTVisitor visitor) {
         if (visitor.visit(this)) {
            this.acceptChild(visitor, this.name);
            this.acceptChild(visitor, this.dataType);
         }

         visitor.endVisit(this);
      }

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

      public void setName(SQLName x) {
         if (x != null) {
            x.setParent(this);
         }

         this.name = x;
      }

      public SQLDataType getDataType() {
         return this.dataType;
      }

      public void setDataType(SQLDataType x) {
         if (x != null) {
            x.setParent(this);
         }

         this.dataType = x;
      }

      public String getComment() {
         return this.comment;
      }

      public void setComment(String comment) {
         this.comment = comment;
      }
   }
}
