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 com.chenyang.druid.util.MySqlUtils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

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

   public SQLDateExpr() {
   }

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

   public SQLDateExpr(Date literal) {
      this.setLiteral(literal);
   }

   public SQLDateExpr(Date literal, TimeZone timeZone) {
      this.setLiteral(literal, timeZone);
   }

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

   public void setLiteral(String literal) {
      this.literal = literal;
   }

   public void setLiteral(Date x) {
      this.setLiteral(x, (TimeZone)null);
   }

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

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

   public String getValue() {
      return this.literal;
   }

   public Date getDate() {
      return this.getDate((TimeZone)null);
   }

   public Date getDate(TimeZone timeZone) {
      return MySqlUtils.parseDate(this.literal, timeZone);
   }

   public boolean addDay(int delta) {
      if (this.literal == null) {
         return false;
      } else {
         SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

         try {
            Date date = format.parse(this.literal);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(5, delta);
            String result_chars = format.format(calendar.getTime());
            this.setLiteral(result_chars);
            return true;
         } catch (ParseException var6) {
            return false;
         }
      }
   }

   public boolean addMonth(int delta) {
      if (this.literal == null) {
         return false;
      } else {
         SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

         try {
            Date date = format.parse(this.literal);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(2, delta);
            String result_chars = format.format(calendar.getTime());
            this.setLiteral(result_chars);
            return true;
         } catch (ParseException var6) {
            return false;
         }
      }
   }

   public boolean addYear(int delta) {
      if (this.literal == null) {
         return false;
      } else {
         SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

         try {
            Date date = format.parse(this.literal);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(1, delta);
            String result_chars = format.format(calendar.getTime());
            this.setLiteral(result_chars);
            return true;
         } catch (ParseException var6) {
            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 {
         SQLDateExpr other = (SQLDateExpr)obj;
         if (this.literal == null) {
            if (other.literal != null) {
               return false;
            }
         } else if (!this.literal.equals(other.literal)) {
            return false;
         }

         return true;
      }
   }

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

      return x;
   }

   public boolean replace(SQLExpr expr, SQLExpr target) {
      return false;
   }

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

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

   public static boolean check(String str) {
      int len;
      if (str != null && (len = str.length()) >= 8) {
         char c0 = str.charAt(0);
         char c1 = str.charAt(1);
         char c2 = str.charAt(2);
         char c3 = str.charAt(3);
         char c4 = str.charAt(4);
         char c5 = str.charAt(5);
         char c6 = str.charAt(6);
         char c7 = str.charAt(7);
         if (c0 < '1' | c0 > '9') {
            return false;
         } else if (c1 < '0' | c1 > '9') {
            return false;
         } else if (c2 < '0' | c2 > '9') {
            return false;
         } else if (c3 < '0' | c3 > '9') {
            return false;
         } else {
            int year = (c0 - 48) * 1000 + (c1 - 48) * 100 + (c2 - 48) * 10 + (c3 - 48);
            if (year < 1000) {
               return false;
            } else if (c4 != '-') {
               return false;
            } else if (c5 < '0' | c5 > '9') {
               return false;
            } else {
               int month;
               int day;
               if (c6 == '-') {
                  month = c5 - 48;
                  if (c7 < '0' | c7 > '9') {
                     return false;
                  }

                  if (len == 8) {
                     day = c7 - 48;
                  } else {
                     if (len != 9) {
                        return false;
                     }

                     char c8 = str.charAt(8);
                     if (c8 < '0' | c8 > '9') {
                        return false;
                     }

                     day = (c7 - 48) * 10 + (c8 - 48);
                  }
               } else {
                  if (c6 < '0' | c6 > '9') {
                     return false;
                  }

                  month = (c5 - 48) * 10 + (c6 - 48);
                  if (c7 != '-') {
                     return false;
                  }

                  if (len == 9) {
                     char c8 = str.charAt(8);
                     if (c8 < '0' | c8 > '9') {
                        return false;
                     }

                     day = c8 - 48;
                  } else {
                     if (len != 10) {
                        return false;
                     }

                     char c8 = str.charAt(8);
                     char c9 = str.charAt(9);
                     if (c8 < '0' | c8 > '9') {
                        return false;
                     }

                     if (c9 < '0' | c9 > '9') {
                        return false;
                     }

                     day = (c8 - 48) * 10 + (c9 - 48);
                  }
               }

               if (month < 1) {
                  return false;
               } else if (day < 1) {
                  return false;
               } else {
                  switch (month) {
                     case 1:
                     case 3:
                     case 5:
                     case 7:
                     case 8:
                     case 10:
                     case 12:
                        if (day > 31) {
                           return false;
                        }

                        return true;
                     case 2:
                        if (day > 29) {
                           return false;
                        }

                        return true;
                     case 4:
                     case 6:
                     case 9:
                     case 11:
                        if (day > 30) {
                           return false;
                        }

                        return true;
                     default:
                        return false;
                  }
               }
            }
         }
      } else {
         return false;
      }
   }

   public static String format(Calendar calendar) {
      if (calendar == null) {
         return null;
      } else {
         int year = calendar.get(1);
         int month = calendar.get(2) + 1;
         int dayOfMonth = calendar.get(5);
         char[] chars = new char[10];
         chars[0] = (char)(year / 1000 + 48);
         chars[1] = (char)(year / 100 % 10 + 48);
         chars[2] = (char)(year / 10 % 10 + 48);
         chars[3] = (char)(year % 10 + 48);
         chars[4] = '-';
         chars[5] = (char)(month / 10 + 48);
         chars[6] = (char)(month % 10 + 48);
         chars[7] = '-';
         chars[8] = (char)(dayOfMonth / 10 + 48);
         chars[9] = (char)(dayOfMonth % 10 + 48);
         return new String(chars);
      }
   }

   public SQLDataType computeDataType() {
      return DATA_TYPE;
   }

   static {
      supportDbTypes = DbType.of(DbType.mysql, DbType.oracle, DbType.presto, DbType.postgresql, DbType.ads, DbType.hive, DbType.odps, DbType.dm, DbType.kingbase);
   }
}
