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

import com.chenyang.druid.sql.ast.SQLExpr;
import com.chenyang.druid.sql.ast.SQLObject;
import com.chenyang.druid.sql.dialect.spark.ast.SparkSqlExprImpl;
import com.chenyang.druid.sql.dialect.spark.ast.expr.SparkColumnSpecExpr;
import com.chenyang.druid.sql.dialect.spark.ast.expr.SparkDefProperty;
import com.chenyang.druid.sql.dialect.spark.ast.expr.SparkSelectTableReference;
import com.chenyang.druid.sql.dialect.spark.ast.expr.SparkTablePartition;
import com.chenyang.druid.sql.dialect.spark.visitor.SparkVisitor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import util.sqlparse.visitor.common.Objects;

public class SparkAlterTableStatement extends SparkStatementImpl {
   private AlterTableType alterTableType;
   private SparkSelectTableReference table;
   private SparkAlterTableReNameTo rename;
   private SparkAlterTableAddColumns addColumns;
   private SparkAlterTableDropColumns dropColumns;
   private SparkAlterTableRenameColumn renameColumn;
   private SparkAlterTableChangeColumn changeColumn;
   private SparkAlterTableReplaceColumns replaceColumns;
   private SparkAlterTableAddOrDropPartition addOrDropPartition;
   private SparkAlterTableSetUnsetProps setUnsetProps;

   public AlterTableType getAlterTableType() {
      return this.alterTableType;
   }

   public void setAlterTableType(AlterTableType alterTableType) {
      this.alterTableType = alterTableType;
   }

   public SparkSelectTableReference getTable() {
      return this.table;
   }

   public void setTable(SparkSelectTableReference table) {
      table.setParent(this);
      this.table = table;
   }

   public SparkAlterTableReNameTo getRename() {
      return this.rename;
   }

   public void setRename(SparkAlterTableReNameTo rename) {
      rename.setParent(this);
      this.rename = rename;
   }

   public SparkAlterTableAddColumns getAddColumns() {
      return this.addColumns;
   }

   public void setAddColumns(SparkAlterTableAddColumns addColumns) {
      addColumns.setParent(this);
      this.addColumns = addColumns;
   }

   public SparkAlterTableDropColumns getDropColumns() {
      return this.dropColumns;
   }

   public void setDropColumns(SparkAlterTableDropColumns dropColumns) {
      dropColumns.setParent(this);
      this.dropColumns = dropColumns;
   }

   public SparkAlterTableRenameColumn getRenameColumn() {
      return this.renameColumn;
   }

   public void setRenameColumn(SparkAlterTableRenameColumn renameColumn) {
      renameColumn.setParent(this);
      this.renameColumn = renameColumn;
   }

   public SparkAlterTableChangeColumn getChangeColumn() {
      return this.changeColumn;
   }

   public void setChangeColumn(SparkAlterTableChangeColumn changeColumn) {
      changeColumn.setParent(this);
      this.changeColumn = changeColumn;
   }

   public SparkAlterTableReplaceColumns getReplaceColumns() {
      return this.replaceColumns;
   }

   public void setReplaceColumns(SparkAlterTableReplaceColumns replaceColumns) {
      replaceColumns.setParent(this);
      this.replaceColumns = replaceColumns;
   }

   public SparkAlterTableAddOrDropPartition getAddOrDropPartition() {
      return this.addOrDropPartition;
   }

   public void setAddOrDropPartition(SparkAlterTableAddOrDropPartition addOrDropPartition) {
      addOrDropPartition.setParent(this);
      this.addOrDropPartition = addOrDropPartition;
   }

   public SparkAlterTableSetUnsetProps getSetUnsetProps() {
      return this.setUnsetProps;
   }

   public void setSetUnsetProps(SparkAlterTableSetUnsetProps setUnsetProps) {
      setUnsetProps.setParent(this);
      this.setUnsetProps = setUnsetProps;
   }

   public SparkAlterTableStatement clone() {
      SparkAlterTableStatement e = new SparkAlterTableStatement();
      e.alterTableType = this.alterTableType;
      e.table = this.table.clone();
      e.rename = this.rename == null ? null : this.rename.clone();
      e.addColumns = this.addColumns == null ? null : this.addColumns.clone();
      e.dropColumns = this.dropColumns == null ? null : this.dropColumns.clone();
      e.renameColumn = this.renameColumn == null ? null : this.renameColumn.clone();
      e.changeColumn = this.changeColumn == null ? null : this.changeColumn.clone();
      e.replaceColumns = this.replaceColumns == null ? null : this.replaceColumns.clone();
      e.addOrDropPartition = this.addOrDropPartition == null ? null : this.addOrDropPartition.clone();
      e.setUnsetProps = this.setUnsetProps == null ? null : this.setUnsetProps.clone();
      return e;
   }

   public boolean equals(Object o) {
      if (this == o) {
         return true;
      } else if (!this.objectNullEquals(this, o)) {
         return false;
      } else {
         SparkAlterTableStatement that = (SparkAlterTableStatement)o;
         if (!this.objectEquals(this.rename, that.rename)) {
            return false;
         } else if (!this.objectEquals(this.addColumns, that.addColumns)) {
            return false;
         } else if (!this.objectEquals(this.dropColumns, that.dropColumns)) {
            return false;
         } else if (!this.objectEquals(this.renameColumn, that.renameColumn)) {
            return false;
         } else if (!this.objectEquals(this.changeColumn, that.changeColumn)) {
            return false;
         } else if (!this.objectEquals(this.replaceColumns, that.replaceColumns)) {
            return false;
         } else if (!this.objectEquals(this.addOrDropPartition, that.addOrDropPartition)) {
            return false;
         } else {
            return this.objectEquals(this.setUnsetProps, that.setUnsetProps);
         }
      }
   }

   public int hashCode() {
      int hashCode = this.alterTableType.hashCode();
      hashCode = 31 * hashCode + this.table.hashCode();
      hashCode = 31 * hashCode + (this.rename == null ? 0 : this.rename.hashCode());
      hashCode = 31 * hashCode + (this.addColumns == null ? 0 : this.addColumns.hashCode());
      hashCode = 31 * hashCode + (this.dropColumns == null ? 0 : this.dropColumns.hashCode());
      hashCode = 31 * hashCode + (this.renameColumn == null ? 0 : this.renameColumn.hashCode());
      hashCode = 31 * hashCode + (this.changeColumn == null ? 0 : this.changeColumn.hashCode());
      hashCode = 31 * hashCode + (this.replaceColumns == null ? 0 : this.replaceColumns.hashCode());
      hashCode = 31 * hashCode + (this.addOrDropPartition == null ? 0 : this.addOrDropPartition.hashCode());
      hashCode = 31 * hashCode + (this.setUnsetProps == null ? 0 : this.setUnsetProps.hashCode());
      return hashCode;
   }

   public void accept0(SparkVisitor v) {
      if (v.visit(this)) {
         this.acceptChild(v, this.table);
         this.acceptChild(v, this.rename);
         this.acceptChild(v, this.addColumns);
         this.acceptChild(v, this.dropColumns);
         this.acceptChild(v, this.renameColumn);
         this.acceptChild(v, this.changeColumn);
         this.acceptChild(v, this.replaceColumns);
         this.acceptChild(v, this.addOrDropPartition);
         this.acceptChild(v, this.setUnsetProps);
      }

      v.endVisit(this);
   }

   public static class SparkAlterTableReNameTo extends SparkSqlExprImpl {
      private SQLExpr name;
      private SparkTablePartition partition;

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

      public void setName(SQLExpr name) {
         this.name = name;
         name.setParent(this);
      }

      public SparkTablePartition getPartition() {
         return this.partition;
      }

      public void setPartition(SparkTablePartition partition) {
         this.partition = partition;
         this.parent.setParent(this);
      }

      public List<SQLObject> getChildren() {
         return Arrays.asList(this.name, this.partition);
      }

      public void accept0(SparkVisitor v) {
         if (v.visit(this)) {
            this.acceptChild(v, this.name);
            this.acceptChild(v, this.partition);
         }

         v.endVisit(this);
      }

      public SparkAlterTableReNameTo clone() {
         SparkAlterTableReNameTo to = new SparkAlterTableReNameTo();
         if (this.name != null) {
            to.name = this.name.clone();
         }

         if (this.partition != null) {
            to.partition = this.partition.clone();
         }

         return to;
      }

      public boolean equals(Object o) {
         if (this == o) {
            return true;
         } else if (!this.objectNullEquals(this, o)) {
            return false;
         } else {
            SparkAlterTableReNameTo that = (SparkAlterTableReNameTo)o;
            if (!this.objectEquals(that.name, this.name)) {
               return false;
            } else {
               return this.objectEquals(that.partition, this.partition);
            }
         }
      }

      public int hashCode() {
         int hash = 31 * (this.name == null ? 0 : this.name.hashCode());
         hash = 31 * hash + (this.partition == null ? 0 : this.partition.hashCode());
         return hash;
      }
   }

   public static class SparkAlterTableAddColumns extends SparkSqlExprImpl {
      private List<SparkColumnSpecExpr> columns = new ArrayList();

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

      public void setColumns(List<SparkColumnSpecExpr> columns) {
         this.columns = columns;

         for(SparkColumnSpecExpr column : columns) {
            column.setParent(this);
         }

      }

      public List<SQLObject> getChildren() {
         ArrayList<SQLObject> sqlExprs = new ArrayList();

         for(SparkColumnSpecExpr column : this.columns) {
            sqlExprs.add(column);
         }

         return sqlExprs;
      }

      public void accept0(SparkVisitor v) {
         if (v.visit(this)) {
            this.acceptChild(v, this.columns);
         }

         v.endVisit(this);
      }

      public SparkAlterTableAddColumns clone() {
         SparkAlterTableAddColumns to = new SparkAlterTableAddColumns();

         for(SparkColumnSpecExpr column : this.columns) {
            to.columns.add(column.clone());
         }

         return to;
      }

      public boolean equals(Object o) {
         if (!this.objectNullEquals(this, o)) {
            return false;
         } else {
            SparkAlterTableAddColumns that = (SparkAlterTableAddColumns)o;
            if (that.columns.size() != this.columns.size()) {
               return false;
            } else {
               for(int i = 0; i < this.columns.size(); ++i) {
                  if (!this.objectEquals(this.columns.get(i), that.columns.get(i))) {
                     return false;
                  }
               }

               return true;
            }
         }
      }

      public int hashCode() {
         return 31 * Objects.hash(this.columns);
      }
   }

   public static class SparkAlterTableDropColumns extends SparkSqlExprImpl {
      private List<SQLObject> columns = new ArrayList();

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

      public void setColumns(List<SQLObject> columns) {
         for(SQLObject column : columns) {
            column.setParent(this);
         }

         this.columns = columns;
      }

      public void addColumn(SQLExpr column) {
         column.setParent(this);
         this.columns.add(column);
      }

      public List<SQLObject> getChildren() {
         return this.columns;
      }

      public void accept0(SparkVisitor v) {
         if (v.visit(this)) {
            this.acceptChild(v, this.columns);
         }

         v.endVisit(this);
      }

      public SparkAlterTableDropColumns clone() {
         SparkAlterTableDropColumns to = new SparkAlterTableDropColumns();

         for(SQLObject column : this.columns) {
            to.columns.add(column.clone());
         }

         return to;
      }

      public boolean equals(Object o) {
         if (!this.objectNullEquals(this, o)) {
            return false;
         } else {
            SparkAlterTableDropColumns that = (SparkAlterTableDropColumns)o;
            if (that.columns.size() != this.columns.size()) {
               return false;
            } else {
               for(int i = 0; i < this.columns.size(); ++i) {
                  if (!this.objectEquals(this.columns.get(i), that.columns.get(i))) {
                     return false;
                  }
               }

               return true;
            }
         }
      }

      public int hashCode() {
         return 31 * Objects.hash(this.columns);
      }
   }

   public static class SparkAlterTableRenameColumn extends SparkSqlExprImpl {
      private SQLExpr column;
      private SQLExpr to;

      public SQLExpr getColumn() {
         return this.column;
      }

      public void setColumn(SQLExpr column) {
         this.column = column;
         column.setParent(this);
      }

      public SQLExpr getTo() {
         return this.to;
      }

      public void setTo(SQLExpr to) {
         this.to = to;
         to.setParent(this);
      }

      public List<SQLObject> getChildren() {
         return Arrays.asList(this.column, this.to);
      }

      public void accept0(SparkVisitor v) {
         if (v.visit(this)) {
            this.acceptChild(v, this.column);
            this.acceptChild(v, this.to);
         }

         v.endVisit(this);
      }

      public SparkAlterTableRenameColumn clone() {
         SparkAlterTableRenameColumn e = new SparkAlterTableRenameColumn();
         e.column = this.column.clone();
         e.to = this.to.clone();
         return e;
      }

      public boolean equals(Object o) {
         if (!this.objectNullEquals(this, o)) {
            return false;
         } else {
            SparkAlterTableRenameColumn that = (SparkAlterTableRenameColumn)o;
            if (!this.objectEquals(this.column, that.column)) {
               return false;
            } else {
               return this.objectEquals(this.to, that.to);
            }
         }
      }

      public int hashCode() {
         int hashCode = 31 * this.column.hashCode();
         return 31 * hashCode + this.to.hashCode();
      }
   }

   public static class SparkAlterTableChangeColumn extends SparkSqlExprImpl {
      private SQLExpr column;
      private SparkColumnSpecExpr spec;

      public SQLExpr getColumn() {
         return this.column;
      }

      public void setColumn(SQLExpr column) {
         column.setParent(this);
         this.column = column;
      }

      public SparkColumnSpecExpr getSpec() {
         return this.spec;
      }

      public void setSpec(SparkColumnSpecExpr spec) {
         spec.setParent(this);
         this.spec = spec;
      }

      public List<SQLObject> getChildren() {
         return Arrays.asList(this.column, this.spec);
      }

      public void accept0(SparkVisitor v) {
         if (v.visit(this)) {
            this.acceptChild(v, this.column);
            this.acceptChild(v, this.spec);
         }

         v.endVisit(this);
      }

      public SparkAlterTableChangeColumn clone() {
         SparkAlterTableChangeColumn e = new SparkAlterTableChangeColumn();
         e.column = this.column.clone();
         e.spec = this.spec.clone();
         return e;
      }

      public boolean equals(Object o) {
         if (!this.objectNullEquals(this, o)) {
            return false;
         } else {
            SparkAlterTableChangeColumn that = (SparkAlterTableChangeColumn)o;
            if (!this.objectEquals(this.column, that.column)) {
               return false;
            } else {
               return this.objectEquals(this.spec, that.spec);
            }
         }
      }

      public int hashCode() {
         int hashCode = 31 * this.column.hashCode();
         return 31 * hashCode + this.spec.hashCode();
      }
   }

   public static class SparkAlterTableReplaceColumns extends SparkSqlExprImpl {
      private List<SparkColumnSpecExpr> columns = new ArrayList();

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

      public void setColumns(List<SparkColumnSpecExpr> columns) {
         for(SQLExpr column : columns) {
            column.setParent(this);
         }

         this.columns = columns;
      }

      public void addColumn(SparkColumnSpecExpr column) {
         column.setParent(this);
         this.columns.add(column);
      }

      public List<SQLObject> getChildren() {
         ArrayList<SQLObject> sqlExprs = new ArrayList();

         for(SparkColumnSpecExpr column : this.columns) {
            sqlExprs.add(column);
         }

         return sqlExprs;
      }

      public void accept0(SparkVisitor v) {
         if (v.visit(this)) {
            this.acceptChild(v, this.columns);
         }

         v.endVisit(this);
      }

      public SparkAlterTableReplaceColumns clone() {
         SparkAlterTableReplaceColumns to = new SparkAlterTableReplaceColumns();

         for(SparkColumnSpecExpr column : this.columns) {
            to.columns.add(column.clone());
         }

         return to;
      }

      public boolean equals(Object o) {
         if (!this.objectNullEquals(this, o)) {
            return false;
         } else {
            SparkAlterTableReplaceColumns that = (SparkAlterTableReplaceColumns)o;
            if (that.columns.size() != this.columns.size()) {
               return false;
            } else {
               for(int i = 0; i < this.columns.size(); ++i) {
                  if (!this.objectEquals(this.columns.get(i), that.columns.get(i))) {
                     return false;
                  }
               }

               return true;
            }
         }
      }

      public int hashCode() {
         return 31 * Objects.hash(this.columns);
      }
   }

   public static class SparkAlterTableAddOrDropPartition extends SparkSqlExprImpl {
      private boolean exists = false;
      private boolean purge = false;
      private boolean add = false;
      private List<SparkTablePartition> partitions = new ArrayList();

      public boolean isExists() {
         return this.exists;
      }

      public void setExists(boolean exists) {
         this.exists = exists;
      }

      public boolean isPurge() {
         return this.purge;
      }

      public void setPurge(boolean purge) {
         this.purge = purge;
      }

      public boolean isAdd() {
         return this.add;
      }

      public void setAdd(boolean add) {
         this.add = add;
      }

      public void addPartition(SparkTablePartition partition) {
         partition.setParent(this);
         this.partitions.add(partition);
      }

      public List<SparkTablePartition> getPartitions() {
         return this.partitions;
      }

      public void setPartitions(List<SparkTablePartition> partitions) {
         this.partitions = partitions;

         for(SparkTablePartition partition : partitions) {
            partition.setParent(this);
         }

      }

      public List<SQLObject> getChildren() {
         ArrayList<SQLObject> sqlExprs = new ArrayList();

         for(SparkTablePartition partition : this.partitions) {
            sqlExprs.add(partition);
         }

         return sqlExprs;
      }

      public void accept0(SparkVisitor v) {
         if (v.visit(this)) {
            this.acceptChild(v, this.partitions);
         }

         v.endVisit(this);
      }

      public SparkAlterTableAddOrDropPartition clone() {
         SparkAlterTableAddOrDropPartition e = new SparkAlterTableAddOrDropPartition();
         e.add = this.add;

         for(SparkTablePartition partition : this.partitions) {
            e.partitions.add(partition.clone());
         }

         return e;
      }

      public boolean equals(Object o) {
         if (!this.objectNullEquals(this, o)) {
            return false;
         } else {
            SparkAlterTableAddOrDropPartition that = (SparkAlterTableAddOrDropPartition)o;
            if (this.add != that.add) {
               return false;
            } else if (this.partitions.size() != that.partitions.size()) {
               return false;
            } else {
               for(int i = 0; i < this.partitions.size(); ++i) {
                  if (!this.objectEquals(this.partitions.get(i), that.partitions.get(i))) {
                     return false;
                  }
               }

               return true;
            }
         }
      }

      public int hashCode() {
         int hash = this.add ? 1 : 0;
         return 31 * hash + Objects.hash(this.partitions);
      }
   }

   public static class SparkAlterTableSetUnsetProps extends SparkSqlExprImpl {
      private boolean exists = false;
      private boolean unset = false;
      private List<SparkDefProperty> props = new ArrayList();
      private SQLExpr serde;
      private SQLExpr fileFormat;
      private SQLExpr location;
      private boolean tblProps = false;

      public boolean isTblProps() {
         return this.tblProps;
      }

      public void setTblProps(boolean tblProps) {
         this.tblProps = tblProps;
      }

      public boolean isExists() {
         return this.exists;
      }

      public void setExists(boolean exists) {
         this.exists = exists;
      }

      public boolean isUnset() {
         return this.unset;
      }

      public void setUnset(boolean unset) {
         this.unset = unset;
      }

      public List<SparkDefProperty> getProps() {
         return this.props;
      }

      public void setProps(List<SparkDefProperty> props) {
         for(SparkDefProperty prop : props) {
            prop.setParent(this);
         }

         this.props = props;
      }

      public SQLExpr getSerde() {
         return this.serde;
      }

      public void setSerde(SQLExpr serde) {
         serde.setParent(this);
         this.serde = serde;
      }

      public SQLExpr getFileFormat() {
         return this.fileFormat;
      }

      public void setFileFormat(SQLExpr fileFormat) {
         fileFormat.setParent(this);
         this.fileFormat = fileFormat;
      }

      public SQLExpr getLocation() {
         return this.location;
      }

      public void setLocation(SQLExpr location) {
         location.setParent(this);
         this.location = location;
      }

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

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

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

         children.addAll(this.props);
         return children;
      }

      public void accept0(SparkVisitor v) {
         if (v.visit(this)) {
            this.acceptChild(v, this.props);
            this.acceptChild(v, this.serde);
            this.acceptChild(v, this.fileFormat);
            this.acceptChild(v, this.location);
         }

         v.endVisit(this);
      }

      public SparkAlterTableSetUnsetProps clone() {
         SparkAlterTableSetUnsetProps e = new SparkAlterTableSetUnsetProps();
         e.tblProps = this.tblProps;
         if (this.serde != null) {
            e.serde = this.serde.clone();
         }

         if (this.fileFormat != null) {
            e.fileFormat = this.fileFormat.clone();
         }

         if (this.location != null) {
            e.location = this.location.clone();
         }

         for(SparkDefProperty prop : this.props) {
            e.props.add(prop.clone());
         }

         return e;
      }

      public boolean equals(Object o) {
         if (!this.objectNullEquals(this, o)) {
            return false;
         } else {
            SparkAlterTableSetUnsetProps that = (SparkAlterTableSetUnsetProps)o;
            if (that.tblProps != this.tblProps) {
               return false;
            } else if (!this.objectEquals(this.serde, that.serde)) {
               return false;
            } else if (!this.objectEquals(this.fileFormat, that.fileFormat)) {
               return false;
            } else if (!this.objectEquals(this.location, that.location)) {
               return false;
            } else if (this.props.size() != that.props.size()) {
               return false;
            } else {
               for(int i = 0; i < this.props.size(); ++i) {
                  if (!this.objectEquals(this.props.get(i), that.props.get(i))) {
                     return false;
                  }
               }

               return true;
            }
         }
      }

      public int hashCode() {
         int hashCode = this.exists ? 31 : 0;
         hashCode = 31 * hashCode + (this.tblProps ? 1 : 2);
         hashCode = 31 * hashCode + (this.unset ? 1 : 2);
         hashCode = 31 * hashCode + (this.serde == null ? 0 : this.serde.hashCode());
         hashCode = 31 * hashCode + (this.fileFormat == null ? 0 : this.fileFormat.hashCode());
         hashCode = 31 * hashCode + (this.location == null ? 0 : this.location.hashCode());
         return 31 * hashCode + Objects.hash(this.props);
      }
   }

   public static enum AlterTableType {
      RENAME_TABLE_NAME,
      ADD_COLUMNS,
      DROP_COLUMNS,
      RENAME_COLUMN,
      ALTER_CHANGE_COLUMN,
      REPLACE_COLUMNS,
      ADD_OR_DROP_PARTITION,
      SET_OR_UNSET_PROPS,
      RECOVER_PARTITIONS;
   }
}
