package util.sqlparse.visitor.mysql;

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.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.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.SQLShowIndexesStatement;
import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlSelectIntoStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqLCacheIndexStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqLShowColumnStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqLShowCreateTableStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterEventStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAnalyzeStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCheckTableStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlChecksumTableStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateEventStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlFlushStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadDataInFileStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadXmlStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlOptimizeStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRenameTableStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRepairTableStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowOpenTablesStatement;
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.mysql.parser.SQLStatementParser;
import util.sqlparse.visitor.mysql.visitor.FormatVisitor;
import util.sqlparse.visitor.mysql.visitor.ValueReplacer;
import util.sqlparse.visitor.mysql.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) {
         return StatementType.insert;
      } else if (statement instanceof MySqlSelectIntoStatement) {
         return StatementType.select;
      } else if (statement instanceof SQLReplaceStatement) {
         return StatementType.replace;
      } else if (statement instanceof SQLMergeStatement) {
         return StatementType.merge;
      } else if (statement instanceof MySqlLoadXmlStatement) {
         return StatementType.loadXml;
      } else if (statement instanceof MySqlLoadDataInFileStatement) {
         return StatementType.loadData;
      } else if (statement instanceof SQLTruncateStatement) {
         return StatementType.truncate;
      } else if (statement instanceof MySqlRenameTableStatement) {
         return StatementType.renameTable;
      } 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) {
         return StatementType.alterView;
      } else 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 MySqlCreateEventStatement) {
         return StatementType.createEvent;
      } else if (statement instanceof MySqlAlterEventStatement) {
         return StatementType.alterEvent;
      } 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 MySqlAnalyzeStatement) {
         return StatementType.analyze;
      } else if (statement instanceof MySqlCheckTableStatement) {
         return StatementType.checkTable;
      } else if (statement instanceof MySqlChecksumTableStatement) {
         return StatementType.checkSumTable;
      } else if (statement instanceof MySqlOptimizeStatement) {
         return StatementType.optimize;
      } else if (statement instanceof MySqlRepairTableStatement) {
         return StatementType.repairTable;
      } else if (statement instanceof MySqLShowColumnStatement) {
         return StatementType.showColumn;
      } else if (statement instanceof MySqLShowCreateTableStatement) {
         return StatementType.showCreateTable;
      } else if (statement instanceof SQLShowIndexesStatement) {
         return StatementType.showIndex;
      } else if (statement instanceof MySqlShowOpenTablesStatement) {
         return StatementType.showOpenTables;
      } else if (statement instanceof MySqlFlushStatement) {
         return StatementType.flush;
      } else if (statement instanceof SQLLoadIndexIntoCacheStatement) {
         return StatementType.loadIndexIntoCache;
      } else {
         return statement instanceof MySqLCacheIndexStatement ? StatementType.cacheIndex : StatementType.other;
      }
   }

   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.mysql);
      WhereVisitor visitor = new WhereVisitor();
      visitor.perform(statements);
      return visitor.getWheres();
   }

   public String format(String sql) {
      List<SQLStatement> statements = SQLUtils.parseStatements(sql, DbType.mysql);
      if (statements != null && statements.size() != 0) {
         FormatVisitor visitor = new FormatVisitor();
         visitor.perform(statements);
         return ((SQLStatement)statements.get(0)).toString();
      } else {
         return "";
      }
   }
}
