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

import com.chenyang.druid.sql.ast.SQLExpr;
import com.chenyang.druid.sql.ast.SQLObjectImpl;
import com.chenyang.druid.sql.ast.SQLOrderBy;
import com.chenyang.druid.sql.ast.SQLOrderingSpecification;
import com.chenyang.druid.sql.ast.SQLReplaceable;
import com.chenyang.druid.sql.ast.expr.SQLIntegerExpr;
import com.chenyang.druid.sql.visitor.SQLASTVisitor;
import java.util.List;

public final class SQLSelectOrderByItem extends SQLObjectImpl implements SQLReplaceable {
   protected SQLExpr expr;
   protected String collate;
   protected SQLOrderingSpecification type;
   protected NullsOrderType nullsOrderType;
   protected transient SQLSelectItem resolvedSelectItem;

   public SQLSelectOrderByItem() {
   }

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

   public SQLSelectOrderByItem(SQLExpr expr, SQLOrderingSpecification type) {
      this.setExpr(expr);
      this.type = type;
   }

   public SQLExpr getExpr() {
      return this.expr;
   }

   public void setExpr(SQLExpr expr) {
      if (expr != null) {
         expr.setParent(this);
      }

      this.expr = expr;
   }

   public String getCollate() {
      return this.collate;
   }

   public void setCollate(String collate) {
      this.collate = collate;
   }

   public SQLOrderingSpecification getType() {
      return this.type;
   }

   public void setType(SQLOrderingSpecification type) {
      this.type = type;
   }

   public NullsOrderType getNullsOrderType() {
      return this.nullsOrderType;
   }

   public void setNullsOrderType(NullsOrderType nullsOrderType) {
      this.nullsOrderType = nullsOrderType;
   }

   protected void accept0(SQLASTVisitor v) {
      if (v.visit(this) && this.expr != null) {
         this.expr.accept(v);
      }

      v.endVisit(this);
   }

   public int hashCode() {
      int prime = 31;
      int result = 1;
      result = 31 * result + (this.collate == null ? 0 : this.collate.hashCode());
      result = 31 * result + (this.expr == null ? 0 : this.expr.hashCode());
      result = 31 * result + (this.type == null ? 0 : this.type.hashCode());
      return result;
   }

   public boolean equals(Object obj) {
      if (this == obj) {
         return true;
      } else if (obj == null) {
         return false;
      } else if (this.getClass() != obj.getClass()) {
         return false;
      } else {
         SQLSelectOrderByItem other = (SQLSelectOrderByItem)obj;
         if (this.collate == null) {
            if (other.collate != null) {
               return false;
            }
         } else if (!this.collate.equals(other.collate)) {
            return false;
         }

         if (this.expr == null) {
            if (other.expr != null) {
               return false;
            }
         } else if (!this.expr.equals(other.expr)) {
            return false;
         }

         return this.type == other.type;
      }
   }

   public boolean replace(SQLExpr expr, SQLExpr target) {
      if (this.expr == expr) {
         if (target instanceof SQLIntegerExpr && this.parent instanceof SQLOrderBy) {
            ((SQLOrderBy)this.parent).getItems().remove(this);
         }

         this.setExpr(target);
         return true;
      } else {
         return false;
      }
   }

   public SQLSelectOrderByItem clone() {
      SQLSelectOrderByItem x = new SQLSelectOrderByItem();
      if (this.expr != null) {
         x.setExpr(this.expr.clone());
      }

      x.collate = this.collate;
      x.type = this.type;
      x.nullsOrderType = this.nullsOrderType;
      return x;
   }

   public SQLSelectItem getResolvedSelectItem() {
      return this.resolvedSelectItem;
   }

   public void setResolvedSelectItem(SQLSelectItem resolvedSelectItem) {
      this.resolvedSelectItem = resolvedSelectItem;
   }

   public boolean isClusterBy() {
      if (this.parent instanceof SQLCreateTableStatement) {
         List<SQLSelectOrderByItem> clusteredBy = ((SQLCreateTableStatement)this.parent).getClusteredBy();
         return clusteredBy.indexOf(this) != -1;
      } else if (!(this.parent instanceof SQLSelectQueryBlock)) {
         return false;
      } else {
         List<SQLSelectOrderByItem> clusterBy = ((SQLSelectQueryBlock)this.parent).getClusterByDirect();
         return clusterBy != null && clusterBy.indexOf(this) != -1;
      }
   }

   public boolean isSortBy() {
      if (this.parent instanceof SQLCreateTableStatement) {
         List<SQLSelectOrderByItem> sortedBy = ((SQLCreateTableStatement)this.parent).getSortedBy();
         return sortedBy.indexOf(this) != -1;
      } else if (!(this.parent instanceof SQLSelectQueryBlock)) {
         return false;
      } else {
         List<SQLSelectOrderByItem> sortedBy = ((SQLSelectQueryBlock)this.parent).getSortByDirect();
         return sortedBy != null && sortedBy.indexOf(this) != -1;
      }
   }

   public boolean isDistributeBy() {
      if (this.parent instanceof SQLSelectQueryBlock) {
         List<SQLSelectOrderByItem> distributeBy = ((SQLSelectQueryBlock)this.parent).getDistributeBy();
         return distributeBy.indexOf(this) != -1;
      } else {
         return false;
      }
   }

   public static enum NullsOrderType {
      NullsFirst,
      NullsLast;

      public String toFormalString() {
         if (NullsFirst.equals(this)) {
            return "NULLS FIRST";
         } else if (NullsLast.equals(this)) {
            return "NULLS LAST";
         } else {
            throw new IllegalArgumentException();
         }
      }
   }
}
