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

import com.chenyang.druid.DbType;
import com.chenyang.druid.sql.ast.SQLDataType;
import com.chenyang.druid.sql.ast.SQLDataTypeImpl;
import com.chenyang.druid.sql.ast.SQLExpr;
import com.chenyang.druid.sql.ast.SQLExprImpl;
import com.chenyang.druid.sql.ast.SQLObject;
import com.chenyang.druid.sql.ast.SQLReplaceable;
import com.chenyang.druid.sql.visitor.SQLASTVisitor;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

public class SQLDateTimeExpr extends SQLExprImpl implements SQLLiteralExpr, SQLValuableExpr, SQLReplaceable {
   public static final SQLDataType DATA_TYPE = new SQLDataTypeImpl("datetime");
   private SQLExpr literal;
   public static long supportDbTypes;

   public SQLDateTimeExpr() {
   }

   public SQLDateTimeExpr(Date now, TimeZone timeZone) {
      this.setLiteral(now, timeZone);
   }

   public void setLiteral(Date x, TimeZone timeZone) {
      if (x == null) {
         this.literal = null;
      } else {
         SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         if (timeZone != null) {
            format.setTimeZone(timeZone);
         }

         String text = format.format(x);
         this.setLiteral(text);
      }
   }

   public SQLDateTimeExpr(String literal) {
      this.setLiteral(literal);
   }

   public SQLExpr getLiteral() {
      return this.literal;
   }

   public void setLiteral(String literal) {
      this.setLiteral((SQLExpr)(new SQLCharExpr(literal)));
   }

   public void setLiteral(SQLExpr x) {
      if (x != null) {
         x.setParent(this);
      }

      this.literal = x;
   }

   public SQLDataType computeDataType() {
      return DATA_TYPE;
   }

   public String getValue() {
      return this.literal instanceof SQLCharExpr ? ((SQLCharExpr)this.literal).getText() : null;
   }

   public boolean replace(SQLExpr expr, SQLExpr target) {
      if (this.literal == expr) {
         this.setLiteral(target);
         return true;
      } else {
         return false;
      }
   }

   protected void accept0(SQLASTVisitor visitor) {
      visitor.visit(this);
      visitor.endVisit(this);
   }

   public int hashCode() {
      int prime = 31;
      int result = 1;
      result = 31 * result + (this.literal == null ? 0 : this.literal.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 {
         SQLDateTimeExpr other = (SQLDateTimeExpr)obj;
         if (this.literal == null) {
            if (other.literal != null) {
               return false;
            }
         } else if (!this.literal.equals(other.literal)) {
            return false;
         }

         return true;
      }
   }

   public SQLDateTimeExpr clone() {
      SQLDateTimeExpr x = new SQLDateTimeExpr();
      if (this.literal != null) {
         x.setLiteral(this.literal.clone());
      }

      return x;
   }

   public List<SQLObject> getChildren() {
      return Collections.emptyList();
   }

   public static boolean isSupport(DbType dbType) {
      return (dbType.mask & supportDbTypes) != 0L;
   }

   public static boolean check(String str) {
      if (str != null && str.length() == 8) {
         if (str.charAt(2) != ':' && str.charAt(5) != ':') {
            return false;
         } else {
            char c0 = str.charAt(0);
            char c1 = str.charAt(1);
            char c3 = str.charAt(3);
            char c4 = str.charAt(4);
            char c6 = str.charAt(6);
            char c7 = str.charAt(7);
            if (c0 >= '0' && c0 <= '9') {
               if (c1 >= '0' && c1 <= '9') {
                  if (c3 >= '0' && c3 <= '9') {
                     if (c4 >= '0' && c4 <= '9') {
                        if (c6 >= '0' && c6 <= '9') {
                           if (c7 >= '0' && c7 <= '9') {
                              int HH = (c0 - 48) * 10 + (c1 - 48);
                              int mm = (c3 - 48) * 10 + (c4 - 48);
                              int ss = (c6 - 48) * 10 + (c7 - 48);
                              return HH <= 24 && mm <= 60 && ss <= 60;
                           } else {
                              return false;
                           }
                        } else {
                           return false;
                        }
                     } else {
                        return false;
                     }
                  } else {
                     return false;
                  }
               } else {
                  return false;
               }
            } else {
               return false;
            }
         }
      } else {
         return false;
      }
   }

   static {
      supportDbTypes = DbType.of(DbType.mysql, DbType.oracle, DbType.presto, DbType.postgresql);
   }
}
