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

import com.chenyang.druid.DbType;
import com.chenyang.druid.sql.SQLUtils;
import com.chenyang.druid.sql.ast.SQLExpr;
import com.chenyang.druid.sql.ast.SQLName;
import com.chenyang.druid.sql.ast.SQLObject;
import com.chenyang.druid.sql.ast.SQLObjectImpl;
import com.chenyang.druid.sql.ast.SQLStatementImpl;
import com.chenyang.druid.sql.ast.expr.SQLCharExpr;
import com.chenyang.druid.sql.ast.expr.SQLIdentifierExpr;
import com.chenyang.druid.sql.ast.expr.SQLLiteralExpr;
import com.chenyang.druid.sql.ast.expr.SQLPropertyExpr;
import com.chenyang.druid.sql.visitor.SQLASTVisitor;
import java.util.ArrayList;
import java.util.List;

public class SQLCreateViewStatement extends SQLStatementImpl implements SQLCreateStatement {
   private boolean orReplace = false;
   private boolean force = false;
   protected SQLSelect subQuery;
   protected boolean ifNotExists = false;
   protected String algorithm;
   protected SQLName definer;
   protected String sqlSecurity;
   protected SQLExprTableSource tableSource;
   protected final List<SQLTableElement> columns = new ArrayList();
   private boolean withCheckOption;
   private boolean withCascaded;
   private boolean withLocal;
   private boolean withReadOnly;
   private SQLLiteralExpr comment;

   public SQLCreateViewStatement() {
   }

   public SQLCreateViewStatement(DbType dbType) {
      super(dbType);
   }

   public String computeName() {
      if (this.tableSource == null) {
         return null;
      } else {
         SQLExpr expr = this.tableSource.getExpr();
         if (expr instanceof SQLName) {
            String name = ((SQLName)expr).getSimpleName();
            return SQLUtils.normalize(name);
         } else {
            return null;
         }
      }
   }

   public String getSchema() {
      SQLName name = this.getName();
      if (name == null) {
         return null;
      } else {
         return name instanceof SQLPropertyExpr ? ((SQLPropertyExpr)name).getOwnernName() : null;
      }
   }

   public boolean isOrReplace() {
      return this.orReplace;
   }

   public void setOrReplace(boolean orReplace) {
      this.orReplace = orReplace;
   }

   public SQLName getName() {
      return this.tableSource == null ? null : (SQLName)this.tableSource.getExpr();
   }

   public void setName(SQLName name) {
      this.setTableSource(new SQLExprTableSource(name));
   }

   public void setName(String name) {
      this.setName((SQLName)(new SQLIdentifierExpr(name)));
   }

   public SQLExprTableSource getTableSource() {
      return this.tableSource;
   }

   public void setTableSource(SQLExprTableSource tableSource) {
      if (tableSource != null) {
         tableSource.setParent(this);
      }

      this.tableSource = tableSource;
   }

   public boolean isWithCheckOption() {
      return this.withCheckOption;
   }

   public void setWithCheckOption(boolean withCheckOption) {
      this.withCheckOption = withCheckOption;
   }

   public boolean isWithCascaded() {
      return this.withCascaded;
   }

   public void setWithCascaded(boolean withCascaded) {
      this.withCascaded = withCascaded;
   }

   public boolean isWithLocal() {
      return this.withLocal;
   }

   public void setWithLocal(boolean withLocal) {
      this.withLocal = withLocal;
   }

   public boolean isWithReadOnly() {
      return this.withReadOnly;
   }

   public void setWithReadOnly(boolean withReadOnly) {
      this.withReadOnly = withReadOnly;
   }

   public SQLSelect getSubQuery() {
      return this.subQuery;
   }

   public void setSubQuery(SQLSelect subQuery) {
      if (subQuery != null) {
         subQuery.setParent(this);
      }

      this.subQuery = subQuery;
   }

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

   public void addColumn(SQLTableElement column) {
      if (column != null) {
         column.setParent(this);
      }

      this.columns.add(column);
   }

   public boolean isIfNotExists() {
      return this.ifNotExists;
   }

   public void setIfNotExists(boolean ifNotExists) {
      this.ifNotExists = ifNotExists;
   }

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

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

      this.comment = comment;
   }

   public String getAlgorithm() {
      return this.algorithm;
   }

   public void setAlgorithm(String algorithm) {
      this.algorithm = algorithm;
   }

   public SQLName getDefiner() {
      return this.definer;
   }

   public void setDefiner(SQLName definer) {
      if (definer != null) {
         definer.setParent(this);
      }

      this.definer = definer;
   }

   public String getSqlSecurity() {
      return this.sqlSecurity;
   }

   public void setSqlSecurity(String sqlSecurity) {
      this.sqlSecurity = sqlSecurity;
   }

   public boolean isForce() {
      return this.force;
   }

   public void setForce(boolean force) {
      this.force = force;
   }

   protected void accept0(SQLASTVisitor visitor) {
      if (visitor.visit(this)) {
         if (this.tableSource != null) {
            this.tableSource.accept(visitor);
         }

         for(int i = 0; i < this.columns.size(); ++i) {
            SQLTableElement column = (SQLTableElement)this.columns.get(i);
            if (column != null) {
               column.accept(visitor);
            }
         }

         if (this.comment != null) {
            this.comment.accept(visitor);
         }

         if (this.subQuery != null) {
            this.subQuery.accept(visitor);
         }
      }

      visitor.endVisit(this);
   }

   public List<SQLObject> getChildren() {
      List<SQLObject> children = new ArrayList();
      if (this.tableSource != null) {
         children.add(this.tableSource);
      }

      children.addAll(this.columns);
      if (this.comment != null) {
         children.add(this.comment);
      }

      if (this.subQuery != null) {
         children.add(this.subQuery);
      }

      return children;
   }

   public SQLCreateViewStatement clone() {
      SQLCreateViewStatement x = new SQLCreateViewStatement();
      x.orReplace = this.orReplace;
      x.force = this.force;
      if (this.subQuery != null) {
         x.setSubQuery(this.subQuery.clone());
      }

      x.ifNotExists = this.ifNotExists;
      x.algorithm = this.algorithm;
      if (this.definer != null) {
         x.setDefiner(this.definer.clone());
      }

      x.sqlSecurity = this.sqlSecurity;
      if (this.tableSource != null) {
         x.setTableSource(this.tableSource.clone());
      }

      for(SQLTableElement column : this.columns) {
         SQLTableElement column2 = column.clone();
         column2.setParent(x);
         x.columns.add(column2);
      }

      x.withCheckOption = this.withCheckOption;
      x.withCascaded = this.withCascaded;
      x.withLocal = this.withLocal;
      x.withReadOnly = this.withReadOnly;
      if (this.comment != null) {
         x.setComment(this.comment.clone());
      }

      return x;
   }

   public static enum Level {
      CASCADED,
      LOCAL;
   }

   public static class Column extends SQLObjectImpl {
      private SQLExpr expr;
      private SQLCharExpr comment;

      public SQLExpr getExpr() {
         return this.expr;
      }

      public void setExpr(SQLExpr expr) {
         if (expr != null) {
            expr.setParent(this);
         }

         this.expr = expr;
      }

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

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

         this.comment = comment;
      }

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

      }
   }
}
