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.expr.SQLIdentifierExpr;
import com.chenyang.druid.sql.ast.statement.SQLExprTableSource;
import com.chenyang.druid.sql.ast.statement.SQLJoinTableSource;
import com.chenyang.druid.sql.ast.statement.SQLTableSource;
import com.chenyang.druid.sql.dialect.spark.visitor.SparkVisitor;
import com.chenyang.druid.sql.visitor.SQLASTVisitor;

public class SparkSelectJoinTableSource extends SQLJoinTableSource implements SparkSelectTableSource {
   protected SparkSelectPivotBase pivot;

   public SparkSelectJoinTableSource(String alias) {
      super(alias);
   }

   public SparkSelectJoinTableSource() {
   }

   public SparkSelectJoinTableSource(SQLTableSource left, JoinType joinType, SQLTableSource right, SQLExpr condition) {
      super(left, joinType, right, condition);
   }

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

   public void setPivot(SparkSelectPivotBase pivot) {
      this.pivot = pivot;
   }

   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.left);
         this.acceptChild(visitor, this.right);
         this.acceptChild(visitor, this.condition);
         this.acceptChild(visitor, this.using);
         this.acceptChild(visitor, this.flashback);
      }

      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 {
            SparkSelectJoinTableSource that = (SparkSelectJoinTableSource)o;
            if (this.pivot != null) {
               if (!this.pivot.equals(that.pivot)) {
                  return false;
               }
            } else if (that.pivot != null) {
               return false;
            }

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

   public int hashCode() {
      int result = this.pivot != null ? this.pivot.hashCode() : 0;
      result = 31 * result + (this.flashback != null ? this.flashback.hashCode() : 0);
      return result;
   }

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

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

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

      return x;
   }

   public void setLeft(String tableName) {
      SQLExprTableSource tableSource;
      if (tableName != null && tableName.length() != 0) {
         tableSource = new SparkSelectTableReference(new SQLIdentifierExpr(tableName));
      } else {
         tableSource = null;
      }

      this.setLeft(tableSource);
   }

   public void setRight(String tableName) {
      SQLExprTableSource tableSource;
      if (tableName != null && tableName.length() != 0) {
         tableSource = new SparkSelectTableReference(new SQLIdentifierExpr(tableName));
      } else {
         tableSource = null;
      }

      this.setRight(tableSource);
   }

   public SQLJoinTableSource join(SQLTableSource right, JoinType joinType, SQLExpr condition) {
      SQLJoinTableSource joined = new SparkSelectJoinTableSource(this, joinType, right, condition);
      return joined;
   }
}
