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

import com.chenyang.druid.sql.SQLUtils;
import com.chenyang.druid.sql.ast.SQLExpr;
import com.chenyang.druid.sql.ast.SQLHint;
import com.chenyang.druid.sql.ast.SQLName;
import com.chenyang.druid.sql.ast.SQLObject;
import com.chenyang.druid.sql.ast.SQLObjectImpl;
import com.chenyang.druid.sql.ast.expr.SQLIdentifierExpr;
import com.chenyang.druid.sql.ast.expr.SQLPropertyExpr;
import com.chenyang.druid.util.FnvHash;
import java.util.ArrayList;
import java.util.List;

public abstract class SQLTableSourceImpl extends SQLObjectImpl implements SQLTableSource {
   protected String alias;
   protected List<SQLHint> hints;
   protected SQLExpr flashback;
   protected long aliasHashCode64;
   protected boolean only;

   public SQLTableSourceImpl() {
   }

   public SQLTableSourceImpl(String alias) {
      this.alias = alias;
   }

   public String getAlias() {
      return this.alias;
   }

   public String getAlias2() {
      if (this.alias != null && this.alias.length() != 0) {
         char first = this.alias.charAt(0);
         if (first != '"' && first != '\'') {
            return this.alias;
         } else {
            char[] chars = new char[this.alias.length() - 2];
            int len = 0;

            for(int i = 1; i < this.alias.length() - 1; ++i) {
               char ch = this.alias.charAt(i);
               if (ch == '\\') {
                  ++i;
                  ch = this.alias.charAt(i);
               }

               chars[len++] = ch;
            }

            return new String(chars, 0, len);
         }
      } else {
         return this.alias;
      }
   }

   public void setAlias(String alias) {
      this.alias = alias;
      this.aliasHashCode64 = 0L;
   }

   public int getHintsSize() {
      return this.hints == null ? 0 : this.hints.size();
   }

   public List<SQLHint> getHints() {
      if (this.hints == null) {
         this.hints = new ArrayList(2);
      }

      return this.hints;
   }

   public void setHints(List<SQLHint> hints) {
      this.hints = hints;
   }

   public SQLTableSource clone() {
      throw new UnsupportedOperationException(this.getClass().getName());
   }

   public String computeAlias() {
      return this.alias;
   }

   public SQLExpr getFlashback() {
      return this.flashback;
   }

   public void setFlashback(SQLExpr flashback) {
      if (flashback != null) {
         flashback.setParent(this);
      }

      this.flashback = flashback;
   }

   public boolean containsAlias(String alias) {
      return SQLUtils.nameEquals(this.alias, alias);
   }

   public long aliasHashCode64() {
      if (this.aliasHashCode64 == 0L && this.alias != null) {
         this.aliasHashCode64 = FnvHash.hashCode64(this.alias);
      }

      return this.aliasHashCode64;
   }

   public SQLColumnDefinition findColumn(String columnName) {
      if (columnName == null) {
         return null;
      } else {
         long hash = FnvHash.hashCode64(columnName);
         return this.findColumn(hash);
      }
   }

   public SQLColumnDefinition findColumn(long columnNameHash) {
      return null;
   }

   public SQLObject resolveColum(long columnNameHash) {
      return this.findColumn(columnNameHash);
   }

   public SQLTableSource findTableSourceWithColumn(String columnName) {
      if (columnName == null) {
         return null;
      } else {
         long hash = FnvHash.hashCode64(columnName);
         return this.findTableSourceWithColumn(hash, columnName, 0);
      }
   }

   public SQLTableSource findTableSourceWithColumn(SQLName columnName) {
      if (columnName instanceof SQLIdentifierExpr) {
         return this.findTableSourceWithColumn(columnName.nameHashCode64(), columnName.getSimpleName(), 0);
      } else {
         if (columnName instanceof SQLPropertyExpr) {
            SQLExpr owner = ((SQLPropertyExpr)columnName).getOwner();
            if (owner instanceof SQLIdentifierExpr) {
               return this.findTableSource(((SQLIdentifierExpr)owner).nameHashCode64());
            }
         }

         return null;
      }
   }

   public SQLTableSource findTableSourceWithColumn(long columnNameHash) {
      return this.findTableSourceWithColumn(columnNameHash, null, 0);
   }

   public SQLTableSource findTableSourceWithColumn(long columnNameHash, String columnName, int option) {
      return null;
   }

   public SQLTableSource findTableSource(String alias) {
      long hash = FnvHash.hashCode64(alias);
      return this.findTableSource(hash);
   }

   public SQLTableSource findTableSource(long alias_hash) {
      long hash = this.aliasHashCode64();
      return hash != 0L && hash == alias_hash ? this : null;
   }

   public boolean equals(Object o) {
      if (this == o) {
         return true;
      } else if (o != null && this.getClass() == o.getClass()) {
         SQLTableSourceImpl that = (SQLTableSourceImpl)o;
         if (this.aliasHashCode64() != that.aliasHashCode64()) {
            return false;
         } else {
            if (this.hints != null) {
               if (!this.hints.equals(that.hints)) {
                  return false;
               }
            } else if (that.hints != null) {
               return false;
            }

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

   public int hashCode() {
      int result = this.hints != null ? this.hints.hashCode() : 0;
      result = 31 * result + (this.flashback != null ? this.flashback.hashCode() : 0);
      result = 31 * result + (int)(this.aliasHashCode64() ^ this.aliasHashCode64() >>> 32);
      return result;
   }

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

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