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

import com.alibaba.druid.sql.ast.SQLCommentHint;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLReplaceable;
import com.alibaba.druid.sql.ast.SQLStatementImpl;
import com.alibaba.druid.sql.parser.ParserException;
import java.util.ArrayList;
import java.util.List;

public abstract class SQLInsertInto extends SQLStatementImpl implements SQLReplaceable {
   protected SQLExprTableSource tableSource;
   protected final List<SQLExpr> columns = new ArrayList();
   protected transient String columnsString;
   protected transient long columnsStringHash;
   protected SQLSelect query;
   protected final List<SQLInsertStatement.ValuesClause> valuesList = new ArrayList();
   protected boolean overwrite = false;
   protected List<SQLAssignItem> partitions;

   public void cloneTo(SQLInsertInto x) {
      if (this.tableSource != null) {
         x.setTableSource(this.tableSource.clone());
      }

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

      if (this.query != null) {
         x.setQuery(this.query.clone());
      }

      for(SQLInsertStatement.ValuesClause v : this.valuesList) {
         SQLInsertStatement.ValuesClause v2 = v.clone();
         v2.setParent(x);
         x.valuesList.add(v2);
      }

      if (this.hint != null) {
         x.setHint(this.hint.clone());
      }

      x.overwrite = this.overwrite;
      if (this.partitions != null) {
         for(SQLAssignItem item : this.partitions) {
            x.addPartition(item.clone());
         }
      }

   }

   public boolean replace(SQLExpr expr, SQLExpr target) {
      for(int i = 0; i < this.columns.size(); ++i) {
         if (this.columns.get(i) == expr) {
            target.setParent(this);
            this.columns.set(i, target);
            return true;
         }
      }

      return false;
   }

   public SQLCommentHint getHint() {
      return this.hint;
   }

   public void setHint(SQLCommentHint x) {
      if (x != null) {
         x.setParent(this);
      }

      this.hint = x;
   }

   public abstract SQLInsertInto clone();

   public String getAlias() {
      return this.tableSource.getAlias();
   }

   public void setAlias(String alias) {
      this.tableSource.setAlias(alias);
   }

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

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

      this.tableSource = tableSource;
   }

   public SQLName getTableName() {
      return (SQLName)this.tableSource.getExpr();
   }

   public void setTableName(SQLName tableName) {
      this.setTableSource(new SQLExprTableSource(tableName));
   }

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

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

   public void setQuery(SQLSelectQuery query) {
      this.setQuery(new SQLSelect(query));
   }

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

      this.query = query;
   }

   public void setQueryNull() {
      this.query = null;
   }

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

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

      this.columns.add(column);
   }

   public SQLInsertStatement.ValuesClause getValues() {
      return this.valuesList.size() == 0 ? null : (SQLInsertStatement.ValuesClause)this.valuesList.get(0);
   }

   public void setValues(SQLInsertStatement.ValuesClause values) {
      if (this.valuesList.size() == 0) {
         this.valuesList.add(values);
      } else {
         this.valuesList.set(0, values);
      }

   }

   public List<SQLInsertStatement.ValuesClause> getValuesList() {
      return this.valuesList;
   }

   public void addValueCause(SQLInsertStatement.ValuesClause valueClause) {
      if (valueClause != null) {
         valueClause.setParent(this);
      }

      this.valuesList.add(valueClause);
   }

   public String getColumnsString() {
      return this.columnsString;
   }

   public long getColumnsStringHash() {
      return this.columnsStringHash;
   }

   public void setColumnsString(String columnsString, long columnsStringHash) {
      this.columnsString = columnsString;
      this.columnsStringHash = columnsStringHash;
   }

   public boolean isOverwrite() {
      return this.overwrite;
   }

   public void setOverwrite(boolean overwrite) {
      this.overwrite = overwrite;
   }

   public void addPartition(SQLAssignItem partition) {
      if (partition != null) {
         partition.setParent(this);
      }

      if (this.partitions == null) {
         this.partitions = new ArrayList();
      }

      this.partitions.add(partition);
   }

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

   public void setSelect(SQLSelect select) {
      throw new ParserException(" Subclass not implement setSelect()");
   }
}
