package util.sqlparse.visitor.oracle.visitor;

import com.alibaba.druid.sql.ast.SQLObject;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
import com.alibaba.druid.sql.ast.statement.SQLLateralViewTableSource;
import com.alibaba.druid.sql.ast.statement.SQLMergeStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource;
import com.alibaba.druid.sql.ast.statement.SQLUnionQuery;
import com.alibaba.druid.sql.ast.statement.SQLUnionQueryTableSource;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.ast.statement.SQLWithSubqueryClause;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleWithSubqueryEntry;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleInsertStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectJoin;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectQueryBlock;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectSubqueryTableSource;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleUpdateStatement;
import com.alibaba.druid.sql.dialect.oracle.visitor.DefaultOracleASTVisitor;
import java.util.List;
import util.sqlparse.visitor.common.scope.Scope;

public abstract class ParseVisitor extends DefaultOracleASTVisitor {
   private boolean debug = false;
   protected Scope scope;

   public ParseVisitor(Scope scope) {
      this.scope = scope;
   }

   public void perform(List<SQLStatement> statements) {
      if (statements != null && statements.size() != 0) {
         for(SQLStatement statement : statements) {
            statement.accept(this);
         }

         this.scope.reset();
      }
   }

   public boolean visit(SQLSelectStatement x) {
      if (this.debug) {
         System.out.println("enter SQLSelectStatement" + x.toString());
      }

      this.scope.enterScope((SQLObject)x);
      return true;
   }

   public void endVisit(SQLSelectStatement x) {
      if (this.debug) {
         System.out.println("exit SQLSelectStatement" + x.toString());
      }

      this.scope.exitScope();
   }

   public boolean visit(SQLInsertStatement x) {
      this.scope.enterScope((SQLObject)x);
      return true;
   }

   public void endVisit(SQLInsertStatement x) {
      this.scope.exitScope();
   }

   public boolean visit(OracleInsertStatement x) {
      return this.visit((SQLInsertStatement)x);
   }

   public void endVisit(OracleInsertStatement x) {
      this.scope.exitScope();
   }

   public boolean visit(OracleMultiInsertStatement x) {
      this.scope.enterScope((SQLObject)x);
      return true;
   }

   public void endVisit(OracleMultiInsertStatement x) {
      this.scope.exitScope();
   }

   public boolean visit(SQLUpdateStatement x) {
      this.scope.enterScope((SQLObject)x);
      return true;
   }

   public void endVisit(SQLUpdateStatement x) {
      this.scope.exitScope();
   }

   public boolean visit(SQLMergeStatement x) {
      this.scope.enterScope((SQLObject)x);
      return true;
   }

   public void endVisit(SQLMergeStatement x) {
      this.scope.exitScope();
   }

   public boolean visit(OracleUpdateStatement x) {
      this.scope.enterScope((SQLObject)x);
      return true;
   }

   public void endVisit(OracleUpdateStatement x) {
      this.scope.exitScope();
   }

   public boolean visit(SQLDeleteStatement x) {
      this.scope.enterScope((SQLObject)x);
      return true;
   }

   public void endVisit(SQLDeleteStatement x) {
      this.scope.exitScope();
   }

   public boolean visit(OracleDeleteStatement x) {
      this.scope.enterScope((SQLObject)x);
      return true;
   }

   public void endVisit(OracleDeleteStatement x) {
      this.scope.exitScope();
   }

   public boolean visit(SQLWithSubqueryClause x) {
      if (this.debug) {
         System.out.println("enter SQLWithSubqueryClause" + x.toString());
      }

      this.scope.enterScope((SQLObject)x);
      return true;
   }

   public void endVisit(SQLWithSubqueryClause x) {
      if (this.debug) {
         System.out.println("exit SQLWithSubqueryClause" + x.toString());
      }

      this.scope.exitScope();
   }

   public boolean visit(SQLWithSubqueryClause.Entry x) {
      if (this.debug) {
         System.out.println("enter SQLWithSubqueryClause.Entry" + x.toString());
      }

      this.scope.enterScope((SQLObject)x);
      return true;
   }

   public void endVisit(SQLWithSubqueryClause.Entry x) {
      if (this.debug) {
         System.out.println("exit SQLWithSubqueryClause.Entry" + x.toString());
      }

      this.scope.exitScope();
   }

   public boolean visit(OracleWithSubqueryEntry x) {
      if (this.debug) {
         System.out.println("enter SQLWithSubqueryClause.Entry" + x.toString());
      }

      this.scope.enterScope((SQLObject)x);
      return true;
   }

   public void endVisit(OracleWithSubqueryEntry x) {
      if (this.debug) {
         System.out.println("exit SQLWithSubqueryClause.Entry" + x.toString());
      }

      this.scope.exitScope();
   }

   public boolean visit(OracleSelectQueryBlock x) {
      if (this.debug) {
         System.out.println("enter OracleSelectQueryBlock " + x.toString());
      }

      this.scope.enterScope((SQLObject)x);
      return true;
   }

   public void endVisit(OracleSelectQueryBlock x) {
      if (this.debug) {
         System.out.println("exit OracleSelectQueryBlock " + x.toString());
      }

      this.scope.exitScope();
   }

   public boolean visit(SQLUnionQuery x) {
      this.scope.enterScope((SQLObject)x);
      return true;
   }

   public void endVisit(SQLUnionQuery x) {
      this.scope.exitScope();
   }

   public boolean visit(SQLLateralViewTableSource x) {
      this.scope.enterScope((SQLObject)x);
      return true;
   }

   public void endVisit(SQLLateralViewTableSource x) {
      this.scope.exitScope();
   }

   public boolean visit(SQLSubqueryTableSource x) {
      if (this.debug) {
         System.out.println("enter SQLSubqueryTableSource" + x.toString());
      }

      this.scope.enterScope((SQLObject)x);
      return true;
   }

   public void endVisit(SQLSubqueryTableSource x) {
      if (this.debug) {
         System.out.println("exit SQLSubqueryTableSource" + x.toString());
      }

      this.scope.exitScope();
   }

   public boolean visit(OracleSelectSubqueryTableSource x) {
      if (this.debug) {
         System.out.println("enter OracleSelectSubqueryTableSource" + x.toString());
      }

      this.scope.enterScope((SQLObject)x);
      return true;
   }

   public void endVisit(OracleSelectSubqueryTableSource x) {
      if (this.debug) {
         System.out.println("exit OracleSelectSubqueryTableSource" + x.toString());
      }

      this.scope.exitScope();
   }

   public boolean visit(SQLJoinTableSource x) {
      return true;
   }

   public boolean visit(SQLUnionQueryTableSource x) {
      if (this.debug) {
         System.out.println("enter SQLUnionQueryTableSource" + x.toString());
      }

      this.scope.enterScope((SQLObject)x);
      return true;
   }

   public void endVisit(SQLUnionQueryTableSource x) {
      if (this.debug) {
         System.out.println("exit SQLUnionQueryTableSource" + x.toString());
      }

      this.scope.exitScope();
   }

   public void endVisit(SQLJoinTableSource x) {
   }

   public boolean visit(OracleSelectJoin x) {
      return true;
   }

   public void endVisit(OracleSelectJoin x) {
   }

   public boolean visit(SQLExprTableSource x) {
      return true;
   }

   public void endVisit(SQLExprTableSource x) {
   }

   public boolean visit(OracleSelectTableReference x) {
      if (!(x.getExpr() instanceof SQLIdentifierExpr) && !(x.getExpr() instanceof SQLPropertyExpr)) {
         if (this.debug) {
            System.out.println("enter OracleSelectTableReference  " + x);
         }

         this.scope.enterScope((SQLObject)x);
      } else if (this.debug) {
         System.out.println("begin OracleSelectTableReference" + x.toString());
      }

      return true;
   }

   public void endVisit(OracleSelectTableReference x) {
      if (!(x.getExpr() instanceof SQLIdentifierExpr) && !(x.getParent() instanceof SQLPropertyExpr)) {
         if (this.debug) {
            System.out.println("exit OracleSelectTableReference  " + x);
         }

         this.scope.exitScope();
      } else if (this.debug) {
         System.out.println("end OracleSelectTableReference" + x.toString());
      }

   }

   protected void acceptChild(List<? extends SQLObject> children) {
      if (children != null && children.size() != 0) {
         for(SQLObject child : children) {
            child.accept(this);
         }

      }
   }

   protected void visitChild(SQLObject x) {
      if (x != null) {
         x.accept(this);
      }
   }

   protected void visitChild(List<? extends SQLObject> x) {
      if (x != null && x.size() != 0) {
         for(SQLObject sqlObject : x) {
            this.visitChild(sqlObject);
         }

      }
   }

   protected boolean isEqual(String name1, String name2) {
      return this.scope.dialector.isEqual(name1, name2);
   }
}
