package util.sqlparse.visitor.dm;

import bean.DataBase;
import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.statement.SQLAlterFunctionStatement;
import com.alibaba.druid.sql.ast.statement.SQLAlterIndexStatement;
import com.alibaba.druid.sql.ast.statement.SQLAlterProcedureStatement;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLAlterViewStatement;
import com.alibaba.druid.sql.ast.statement.SQLBlockStatement;
import com.alibaba.druid.sql.ast.statement.SQLCallStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateFunctionStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateIndexStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateProcedureStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateViewStatement;
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropEventStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropFunctionStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropIndexStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropProcedureStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropTriggerStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropUserStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropViewStatement;
import com.alibaba.druid.sql.ast.statement.SQLGrantStatement;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLLoadIndexIntoCacheStatement;
import com.alibaba.druid.sql.ast.statement.SQLMergeStatement;
import com.alibaba.druid.sql.ast.statement.SQLReplaceStatement;
import com.alibaba.druid.sql.ast.statement.SQLRevokeStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLSetStatement;
import com.alibaba.druid.sql.ast.statement.SQLShowIndexesStatement;
import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.dialect.dm.ast.stmt.DmAlterTriggerStatement;
import com.alibaba.druid.sql.dialect.dm.ast.stmt.DmAlterViewStatment;
import com.alibaba.druid.sql.dialect.dm.ast.stmt.DmCreatePackageStatement;
import com.alibaba.druid.sql.dialect.dm.ast.stmt.DmCreateSchemaStatement;
import com.alibaba.druid.sql.dialect.dm.ast.stmt.DmCreateSynonymStatement;
import com.alibaba.druid.sql.dialect.dm.ast.stmt.DmExecuteImmediateStatement;
import com.alibaba.druid.sql.dialect.dm.ast.stmt.DmLockTableStatement;
import com.alibaba.druid.sql.dialect.dm.ast.stmt.DmMultiInsertStatement;
import com.alibaba.druid.sql.dialect.dm.ast.stmt.DmPrintStatement;
import java.util.List;
import java.util.Map;
import util.sqlparse.visitor.common.bean.SQLResult;
import util.sqlparse.visitor.common.bean.StatementType;
import util.sqlparse.visitor.common.bean.ValueInfo;
import util.sqlparse.visitor.dm.parser.SQLStatementParser;
import util.sqlparse.visitor.dm.visitor.FormatVisitor;
import util.sqlparse.visitor.dm.visitor.ValueReplacer;
import util.sqlparse.visitor.dm.visitor.WhereVisitor;

public class SQLParser {
   public SQLResult parse(String sql, DataBase dataBase, String schema) {
      if (sql != null && sql.length() != 0) {
         return SQLStatementParser.parse(sql, dataBase, schema);
      } else {
         throw new IllegalArgumentException("sql");
      }
   }

   public SQLResult parse(SQLStatement statement, DataBase dataBase, String schema) {
      if (statement == null) {
         throw new IllegalArgumentException("statement");
      } else {
         return SQLStatementParser.parse(statement, dataBase, schema);
      }
   }

   public static StatementType getStatementType(SQLStatement statement) {
      if (statement instanceof SQLSelectStatement) {
         return StatementType.select;
      } else if (statement instanceof SQLUpdateStatement) {
         return StatementType.update;
      } else if (statement instanceof SQLDeleteStatement) {
         return StatementType.delete;
      } else if (!(statement instanceof SQLInsertStatement) && !(statement instanceof DmMultiInsertStatement)) {
         if (statement instanceof SQLReplaceStatement) {
            return StatementType.replace;
         } else if (statement instanceof SQLMergeStatement) {
            return StatementType.merge;
         } else if (statement instanceof SQLTruncateStatement) {
            return StatementType.truncate;
         } else if (statement instanceof SQLCreateTableStatement) {
            return StatementType.createTable;
         } else if (statement instanceof SQLAlterTableStatement) {
            return StatementType.alterTable;
         } else if (statement instanceof SQLDropTableStatement) {
            return StatementType.dropTable;
         } else if (statement instanceof SQLCreateIndexStatement) {
            return StatementType.createIndex;
         } else if (statement instanceof SQLAlterIndexStatement) {
            return StatementType.alterIndex;
         } else if (statement instanceof SQLDropIndexStatement) {
            return StatementType.dropIndex;
         } else if (statement instanceof SQLCreateViewStatement) {
            return StatementType.createView;
         } else if (!(statement instanceof SQLAlterViewStatement) && !(statement instanceof DmAlterViewStatment)) {
            if (statement instanceof SQLDropViewStatement) {
               return StatementType.dropView;
            } else if (statement instanceof SQLCreateProcedureStatement) {
               return StatementType.createProc;
            } else if (statement instanceof SQLAlterProcedureStatement) {
               return StatementType.alterProc;
            } else if (statement instanceof SQLDropProcedureStatement) {
               return StatementType.dropProc;
            } else if (statement instanceof SQLCreateFunctionStatement) {
               return StatementType.createFunction;
            } else if (statement instanceof SQLAlterFunctionStatement) {
               return StatementType.alterFunction;
            } else if (statement instanceof SQLDropFunctionStatement) {
               return StatementType.dropFunction;
            } else if (statement instanceof SQLCreateTriggerStatement) {
               return StatementType.createTrigger;
            } else if (statement instanceof SQLDropTriggerStatement) {
               return StatementType.dropTrigger;
            } else if (statement instanceof DmAlterTriggerStatement) {
               return StatementType.alterTrigger;
            } else if (statement instanceof SQLDropEventStatement) {
               return StatementType.dropEvent;
            } else if (statement instanceof SQLRevokeStatement) {
               return StatementType.revoke;
            } else if (statement instanceof SQLGrantStatement) {
               return StatementType.grant;
            } else if (statement instanceof SQLCallStatement) {
               return StatementType.callProc;
            } else if (statement instanceof SQLShowIndexesStatement) {
               return StatementType.showIndex;
            } else if (statement instanceof SQLLoadIndexIntoCacheStatement) {
               return StatementType.loadIndexIntoCache;
            } else if (statement instanceof DmCreateSchemaStatement) {
               return StatementType.createSchema;
            } else if (statement instanceof DmCreateSynonymStatement) {
               return StatementType.createSynonym;
            } else if (statement instanceof SQLDropUserStatement) {
               return StatementType.dropUser;
            } else if (statement instanceof DmExecuteImmediateStatement) {
               return StatementType.executeImmediate;
            } else if (statement instanceof DmLockTableStatement) {
               return StatementType.lockTable;
            } else if (statement instanceof DmPrintStatement) {
               return StatementType.print;
            } else if (statement instanceof SQLSetStatement) {
               return StatementType.set;
            } else if (statement instanceof SQLBlockStatement) {
               return StatementType.block;
            } else {
               return statement instanceof DmCreatePackageStatement ? StatementType.createPackage : StatementType.other;
            }
         } else {
            return StatementType.alterView;
         }
      } else {
         return StatementType.insert;
      }
   }

   public void replace(List<ValueInfo> values, Map<String, String> replaceValue) {
      ValueReplacer replacer = new ValueReplacer(replaceValue);
      replacer.replaceValues(values);
   }

   public void replace(List<ValueInfo> values, List<Map> whereList) {
      ValueReplacer replacer = new ValueReplacer(whereList);
      replacer.replaceValuesWithList(values);
   }

   public List<String> where(String sql) {
      List<SQLStatement> statements = SQLUtils.parseStatements(sql, DbType.dm);
      WhereVisitor visitor = new WhereVisitor();
      visitor.perform(statements);
      return visitor.getWheres();
   }

   public String format(String sql) {
      List<SQLStatement> statements = SQLUtils.parseStatements(sql, DbType.dm);
      FormatVisitor visitor = new FormatVisitor();
      visitor.perform(statements);
      return ((SQLStatement)statements.get(0)).toString();
   }
}
