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

import com.chenyang.druid.sql.SQLUtils;
import com.chenyang.druid.sql.ast.SQLExpr;
import com.chenyang.druid.sql.ast.statement.SQLExprTableSource;
import com.chenyang.druid.sql.dialect.oracle.ast.clause.SampleClause;
import com.chenyang.druid.sql.dialect.spark.visitor.SparkVisitor;
import com.chenyang.druid.sql.visitor.SQLASTVisitor;

public class SparkSelectTableReference extends SQLExprTableSource implements SparkSelectTableSource {
   private boolean only = false;
   protected SparkSelectPivotBase pivot;
   protected SparkTablePartition partition;
   protected SampleClause sampleClause;
   protected SparkSampleExpr sample;

   public SparkSelectTableReference() {
   }

   public SparkSelectTableReference(SQLExpr expr) {
      this.setExpr(expr);
   }

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

   public void setPartition(SparkTablePartition partition) {
      if (partition != null) {
         partition.setParent(this);
      }

      this.partition = partition;
   }

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

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

   public SampleClause getSampleClause() {
      return this.sampleClause;
   }

   public void setSampleClause(SampleClause sampleClause) {
      if (sampleClause != null) {
         sampleClause.setParent(this);
      }

      this.sampleClause = sampleClause;
   }

   public SparkSelectPivotBase getPivot() {
      return this.pivot;
   }

   public void setPivot(SparkSelectPivotBase pivot) {
      if (pivot != null) {
         pivot.setParent(this);
      }

      this.pivot = pivot;
   }

   public SparkSampleExpr getSample() {
      return this.sample;
   }

   public void setSample(SparkSampleExpr sample) {
      this.sample = sample;
   }

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

   }

   public void accept0(SparkVisitor visitor) {
      if (visitor.visit(this)) {
         this.acceptChild(visitor, this.expr);
         this.acceptChild(visitor, this.partition);
         this.acceptChild(visitor, this.sampleClause);
         this.acceptChild(visitor, this.sample);
         this.acceptChild(visitor, this.pivot);
      }

      visitor.endVisit(this);
   }

   public boolean equals(Object o) {
      if (this == o) {
         return true;
      } else if (o != null && this.getClass() == o.getClass()) {
         if (!super.equals(o)) {
            return false;
         } else {
            SparkSelectTableReference that = (SparkSelectTableReference)o;
            if (this.only != that.only) {
               return false;
            } else {
               if (this.pivot != null) {
                  if (!this.pivot.equals(that.pivot)) {
                     return false;
                  }
               } else if (that.pivot != null) {
                  return false;
               }

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

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

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

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

   public int hashCode() {
      int result = super.hashCode();
      result = 31 * result + (this.only ? 1 : 0);
      result = 31 * result + (this.pivot != null ? this.pivot.hashCode() : 0);
      result = 31 * result + (this.partition != null ? this.partition.hashCode() : 0);
      result = 31 * result + (this.sampleClause != null ? this.sampleClause.hashCode() : 0);
      result = 31 * result + (this.sample != null ? this.sample.hashCode() : 0);
      result = 31 * result + (this.flashback != null ? this.flashback.hashCode() : 0);
      return result;
   }

   public String toString() {
      return SQLUtils.toOracleString(this);
   }

   public SparkSelectTableReference clone() {
      SparkSelectTableReference x = new SparkSelectTableReference();
      this.cloneTo(x);
      x.only = this.only;
      if (this.pivot != null) {
         x.setPivot(this.pivot.clone());
      }

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

      if (this.sampleClause != null) {
         x.setSampleClause(this.sampleClause.clone());
      }

      if (this.sample != null) {
         x.setSample(this.sample.clone());
      }

      if (this.flashback != null) {
         this.setFlashback(this.flashback.clone());
      }

      return x;
   }
}
