package com.chenyang.druid.sql.dialect.oracle.ast.stmt;

import com.chenyang.druid.DbType;
import com.chenyang.druid.sql.ast.SQLExpr;
import com.chenyang.druid.sql.ast.SQLHint;
import com.chenyang.druid.sql.ast.SQLReplaceable;
import com.chenyang.druid.sql.ast.statement.SQLUpdateStatement;
import com.chenyang.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
import com.chenyang.druid.sql.visitor.SQLASTVisitor;
import java.util.ArrayList;
import java.util.List;

public class OracleUpdateStatement extends SQLUpdateStatement implements OracleStatement, SQLReplaceable {
   private List<SQLHint> hints = new ArrayList(1);
   private boolean only = false;
   private String alias;
   private final List<SQLExpr> returningInto = new ArrayList();

   public OracleUpdateStatement() {
      super(DbType.oracle);
   }

   public List<SQLExpr> getReturningInto() {
      return this.returningInto;
   }

   public void addReturningInto(SQLExpr returningInto) {
      if (returningInto != null) {
         returningInto.setParent(this);
         this.returningInto.add(returningInto);
      }
   }

   protected void accept0(SQLASTVisitor visitor) {
      if (visitor instanceof OracleASTVisitor) {
         this.accept0((OracleASTVisitor)visitor);
      } else {
         super.accept(visitor);
      }
   }

   public void accept0(OracleASTVisitor visitor) {
      if (visitor.visit(this)) {
         this.acceptChild(visitor, this.hints);
         this.acceptChild(visitor, this.tableSource);
         this.acceptChild(visitor, this.items);
         this.acceptChild(visitor, this.where);
         this.acceptChild(visitor, this.returning);
         this.acceptChild(visitor, this.returningInto);
      }

      visitor.endVisit(this);
   }

   public boolean replace(SQLExpr expr, SQLExpr target) {
      boolean replace = super.replace(expr, target);
      if (replace) {
         return true;
      } else {
         for(int i = this.returningInto.size() - 1; i >= 0; --i) {
            if (this.returningInto.get(i) == expr) {
               target.setParent(this);
               this.returningInto.set(i, target);
               return true;
            }
         }

         return false;
      }
   }

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

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

   public boolean isOnly() {
      return this.only;
   }

   public void setOnly(boolean only) {
      this.only = only;
   }

   public int getHintsSize() {
      return this.hints == null ? 0 : this.hints.size();
   }

   public List<SQLHint> getHints() {
      if (this.hints == null) {
         this.hints = new ArrayList(2);
      }

      return this.hints;
   }

   public void setHints(List<SQLHint> hints) {
      this.hints = hints;
   }

   public boolean equals(Object o) {
      if (this == o) {
         return true;
      } else if (o != null && this.getClass() == o.getClass()) {
         OracleUpdateStatement that = (OracleUpdateStatement)o;
         if (this.with != null) {
            if (!this.with.equals(that.getWith())) {
               return false;
            }
         } else if (that.getWith() != null) {
            return false;
         }

         if (!this.items.equals(that.getItems())) {
            return false;
         } else {
            if (this.where != null) {
               if (!this.where.equals(that.getWhere())) {
                  return false;
               }
            } else if (that.getWhere() != null) {
               return false;
            }

            if (this.from != null) {
               if (!this.from.equals(that.getFrom())) {
                  return false;
               }
            } else if (that.getFrom() != null) {
               return false;
            }

            if (this.hints != null) {
               if (!this.hints.equals(that.hints)) {
                  return false;
               }
            } else if (that.hints != null) {
               return false;
            }

            if (this.tableSource != null) {
               if (!this.tableSource.equals(that.tableSource)) {
                  return false;
               }
            } else if (that.tableSource != null) {
               return false;
            }

            if (this.returning != null) {
               if (!this.returning.equals(that.returning)) {
                  return false;
               }
            } else if (that.returning != null) {
               return false;
            }

            return this.orderBy != null ? this.orderBy.equals(that.orderBy) : that.orderBy == null;
         }
      } else {
         return false;
      }
   }

   public int hashCode() {
      int result = this.with != null ? this.with.hashCode() : 0;
      result = 31 * result + this.items.hashCode();
      result = 31 * result + (this.where != null ? this.where.hashCode() : 0);
      result = 31 * result + (this.from != null ? this.from.hashCode() : 0);
      result = 31 * result + (this.tableSource != null ? this.tableSource.hashCode() : 0);
      result = 31 * result + (this.returning != null ? this.returning.hashCode() : 0);
      result = 31 * result + (this.orderBy != null ? this.orderBy.hashCode() : 0);
      result = 31 * result + (this.hints != null ? this.hints.hashCode() : 0);
      return result;
   }
}
