package com.alibaba.druid.sql.ast.statement;

import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLObject;
import com.alibaba.druid.sql.ast.SQLPartitionBy;
import com.alibaba.druid.sql.ast.SQLReplaceable;
import com.alibaba.druid.sql.ast.SQLStatementImpl;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSegmentAttributes;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.util.FnvHash;
import java.util.ArrayList;
import java.util.List;

public class SQLCreateMaterializedViewStatement extends SQLStatementImpl implements OracleSegmentAttributes, SQLCreateStatement, SQLReplaceable {
   private SQLName name;
   private List<SQLName> columns = new ArrayList();
   private boolean refreshFast;
   private boolean refreshComplete;
   private boolean refreshForce;
   private boolean refreshOnCommit;
   private boolean refreshOnDemand;
   private boolean refreshStartWith;
   private boolean refreshNext;
   private boolean buildImmediate;
   private boolean buildDeferred;
   private SQLSelect query;
   private Integer pctfree;
   private Integer pctused;
   private Integer initrans;
   private Integer maxtrans;
   private Integer pctincrease;
   private Integer freeLists;
   private Boolean compress;
   private Integer compressLevel;
   private boolean compressForOltp;
   private Integer pctthreshold;
   private Boolean logging;
   private Boolean cache;
   protected SQLName tablespace;
   protected SQLObject storage;
   private Boolean parallel;
   private Integer parallelValue;
   private Boolean enableQueryRewrite;
   private SQLPartitionBy partitionBy;
   private SQLExpr startWith;
   private SQLExpr next;
   private boolean withRowId;
   protected boolean refreshOnOverWrite;
   protected List<SQLTableElement> tableElementList = new ArrayList();
   protected SQLName distributedByType;
   protected List<SQLName> distributedBy = new ArrayList();
   protected final List<SQLAssignItem> tableOptions = new ArrayList();
   protected SQLExpr comment;

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

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

      this.name = name;
   }

   public List<SQLName> getColumns() {
      return this.columns;
   }

   public SQLSelect getQuery() {
      return this.query;
   }

   public void setQuery(SQLSelect query) {
      if (query != null) {
         query.setParent(this);
      }

      this.query = query;
   }

   public boolean isBuildImmediate() {
      return this.buildImmediate;
   }

   public void setBuildImmediate(boolean buildImmediate) {
      this.buildImmediate = buildImmediate;
   }

   public boolean isBuildDeferred() {
      return this.buildDeferred;
   }

   public void setBuildDeferred(boolean buildDeferred) {
      this.buildDeferred = buildDeferred;
   }

   public boolean isRefresh() {
      return this.refreshFast || this.refreshComplete || this.refreshForce || this.refreshOnDemand || this.refreshOnCommit || this.refreshStartWith || this.refreshNext;
   }

   public boolean isRefreshFast() {
      return this.refreshFast;
   }

   public void setRefreshFast(boolean refreshFast) {
      this.refreshFast = refreshFast;
   }

   public boolean isRefreshComplete() {
      return this.refreshComplete;
   }

   public void setRefreshComplete(boolean refreshComplete) {
      this.refreshComplete = refreshComplete;
   }

   public boolean isRefreshForce() {
      return this.refreshForce;
   }

   public void setRefreshForce(boolean refreshForce) {
      this.refreshForce = refreshForce;
   }

   public boolean isRefreshOnCommit() {
      return this.refreshOnCommit;
   }

   public void setRefreshOnCommit(boolean refreshOnCommit) {
      this.refreshOnCommit = refreshOnCommit;
   }

   public boolean isRefreshOnDemand() {
      return this.refreshOnDemand;
   }

   public void setRefreshOnDemand(boolean refreshOnDemand) {
      this.refreshOnDemand = refreshOnDemand;
   }

   public boolean isRefreshOnOverWrite() {
      return this.refreshOnOverWrite;
   }

   public void setRefreshOnOverWrite(boolean refreshOnOverWrite) {
      this.refreshOnOverWrite = refreshOnOverWrite;
   }

   public boolean isRefreshStartWith() {
      return this.refreshStartWith;
   }

   public void setRefreshStartWith(boolean refreshStartWith) {
      this.refreshStartWith = refreshStartWith;
   }

   public boolean isRefreshNext() {
      return this.refreshNext;
   }

   public void setRefreshNext(boolean refreshNext) {
      this.refreshNext = refreshNext;
   }

   public Integer getPctfree() {
      return this.pctfree;
   }

   public void setPctfree(Integer pctfree) {
      this.pctfree = pctfree;
   }

   public Integer getPctused() {
      return this.pctused;
   }

   public void setPctused(Integer pctused) {
      this.pctused = pctused;
   }

   public Integer getInitrans() {
      return this.initrans;
   }

   public void setInitrans(Integer initrans) {
      this.initrans = initrans;
   }

   public Integer getMaxtrans() {
      return this.maxtrans;
   }

   public void setMaxtrans(Integer maxtrans) {
      this.maxtrans = maxtrans;
   }

   public Integer getPctincrease() {
      return this.pctincrease;
   }

   public void setPctincrease(Integer pctincrease) {
      this.pctincrease = pctincrease;
   }

   public Integer getFreeLists() {
      return this.freeLists;
   }

   public void setFreeLists(Integer freeLists) {
      this.freeLists = freeLists;
   }

   public Boolean getCompress() {
      return this.compress;
   }

   public void setCompress(Boolean compress) {
      this.compress = compress;
   }

   public Integer getCompressLevel() {
      return this.compressLevel;
   }

   public void setCompressLevel(Integer compressLevel) {
      this.compressLevel = compressLevel;
   }

   public boolean isCompressForOltp() {
      return this.compressForOltp;
   }

   public void setCompressForOltp(boolean compressForOltp) {
      this.compressForOltp = compressForOltp;
   }

   public Integer getPctthreshold() {
      return this.pctthreshold;
   }

   public void setPctthreshold(Integer pctthreshold) {
      this.pctthreshold = pctthreshold;
   }

   public Boolean getLogging() {
      return this.logging;
   }

   public void setLogging(Boolean logging) {
      this.logging = logging;
   }

   public SQLName getTablespace() {
      return this.tablespace;
   }

   public void setTablespace(SQLName tablespace) {
      if (tablespace != null) {
         tablespace.setParent(this);
      }

      this.tablespace = tablespace;
   }

   public SQLObject getStorage() {
      return this.storage;
   }

   public void setStorage(SQLObject storage) {
      if (storage != null) {
         storage.setParent(this);
      }

      this.storage = storage;
   }

   public Boolean getParallel() {
      return this.parallel;
   }

   public void setParallel(Boolean parallel) {
      this.parallel = parallel;
   }

   public Integer getParallelValue() {
      return this.parallelValue;
   }

   public void setParallelValue(Integer parallelValue) {
      this.parallelValue = parallelValue;
   }

   public Boolean getEnableQueryRewrite() {
      return this.enableQueryRewrite;
   }

   public void setEnableQueryRewrite(Boolean enableQueryRewrite) {
      this.enableQueryRewrite = enableQueryRewrite;
   }

   public Boolean getCache() {
      return this.cache;
   }

   public void setCache(Boolean cache) {
      this.cache = cache;
   }

   public SQLPartitionBy getPartitionBy() {
      return this.partitionBy;
   }

   public List<SQLTableElement> getTableElementList() {
      return this.tableElementList;
   }

   public List<SQLName> getDistributedBy() {
      return this.distributedBy;
   }

   public SQLName getDistributedByType() {
      return this.distributedByType;
   }

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

      this.distributedByType = x;
   }

   public SQLExpr getStartWith() {
      return this.startWith;
   }

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

      this.startWith = x;
   }

   public SQLExpr getNext() {
      return this.next;
   }

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

      this.next = x;
   }

   public void setPartitionBy(SQLPartitionBy x) {
      if (x != null) {
         x.setParent(this);
      }

      this.partitionBy = x;
   }

   public boolean isWithRowId() {
      return this.withRowId;
   }

   public void setWithRowId(boolean withRowId) {
      this.withRowId = withRowId;
   }

   public void addOption(String name, SQLExpr value) {
      SQLAssignItem assignItem = new SQLAssignItem(new SQLIdentifierExpr(name), value);
      assignItem.setParent(this);
      this.tableOptions.add(assignItem);
   }

   public List<SQLAssignItem> getTableOptions() {
      return this.tableOptions;
   }

   public SQLExpr getOption(String name) {
      if (name == null) {
         return null;
      } else {
         long hash64 = FnvHash.hashCode64(name);

         for(SQLAssignItem item : this.tableOptions) {
            SQLExpr target = item.getTarget();
            if (target instanceof SQLIdentifierExpr && ((SQLIdentifierExpr)target).hashCode64() == hash64) {
               return item.getValue();
            }
         }

         return null;
      }
   }

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

   public void setComment(SQLExpr comment) {
      if (comment != null) {
         comment.setParent(this);
      }

      this.comment = comment;
   }

   protected void accept0(SQLASTVisitor visitor) {
      if (visitor.visit(this)) {
         this.acceptChild(visitor, this.name);
         this.acceptChild(visitor, this.columns);
         this.acceptChild(visitor, this.partitionBy);
         this.acceptChild(visitor, this.query);
         this.acceptChild(visitor, this.tableElementList);
         this.acceptChild(visitor, this.distributedBy);
         this.acceptChild(visitor, this.distributedByType);
         this.acceptChild(visitor, this.startWith);
         this.acceptChild(visitor, this.next);
         this.acceptChild(visitor, this.tableOptions);
         this.acceptChild(visitor, this.comment);
      }

      visitor.endVisit(this);
   }

   public boolean replace(SQLExpr expr, SQLExpr target) {
      if (expr == this.name) {
         this.setName((SQLName)target);
         return true;
      } else if (expr == this.next) {
         this.setNext(target);
         return true;
      } else if (expr == this.startWith) {
         this.setStartWith(target);
         return true;
      } else {
         return false;
      }
   }
}
