package util.sqlparse.visitor.mariadb;

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.mariadb.ast.clause.MariadbSelectIntoStatement;
import com.alibaba.druid.sql.dialect.mariadb.ast.statement.MariadbAlterEventStatement;
import com.alibaba.druid.sql.dialect.mariadb.ast.statement.MariadbAnalyzeStatement;
import com.alibaba.druid.sql.dialect.mariadb.ast.statement.MariadbCacheIndexStatement;
import com.alibaba.druid.sql.dialect.mariadb.ast.statement.MariadbCheckTableStatement;
import com.alibaba.druid.sql.dialect.mariadb.ast.statement.MariadbChecksumTableStatement;
import com.alibaba.druid.sql.dialect.mariadb.ast.statement.MariadbCreateEventStatement;
import com.alibaba.druid.sql.dialect.mariadb.ast.statement.MariadbFlushStatement;
import com.alibaba.druid.sql.dialect.mariadb.ast.statement.MariadbLoadDataInFileStatement;
import com.alibaba.druid.sql.dialect.mariadb.ast.statement.MariadbLoadXmlStatement;
import com.alibaba.druid.sql.dialect.mariadb.ast.statement.MariadbOptimizeStatement;
import com.alibaba.druid.sql.dialect.mariadb.ast.statement.MariadbRenameTableStatement;
import com.alibaba.druid.sql.dialect.mariadb.ast.statement.MariadbRepairTableStatement;
import com.alibaba.druid.sql.dialect.mariadb.ast.statement.MariadbShowColumnStatement;
import com.alibaba.druid.sql.dialect.mariadb.ast.statement.MariadbShowCreateTableStatement;
import com.alibaba.druid.sql.dialect.mariadb.ast.statement.MariadbShowOpenTablesStatement;
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.mariadb.parser.SQLStatementParser;
import util.sqlparse.visitor.mariadb.visitor.FormatVisitor;
import util.sqlparse.visitor.mariadb.visitor.ValueReplacer;
import util.sqlparse.visitor.mariadb.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 MariadbSelectIntoStatement) {
         return StatementType.select;
      } else if (statement instanceof SQLReplaceStatement) {
         return StatementType.replace;
      } else if (statement instanceof SQLMergeStatement) {
         return StatementType.merge;
      } else if (statement instanceof MariadbLoadXmlStatement) {
         return StatementType.loadXml;
      } else if (statement instanceof MariadbLoadDataInFileStatement) {
         return StatementType.loadData;
      } else if (statement instanceof SQLTruncateStatement) {
         return StatementType.truncate;
      } else if (statement instanceof MariadbRenameTableStatement) {
         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 MariadbCreateEventStatement) {
         return StatementType.createEvent;
      } else if (statement instanceof MariadbAlterEventStatement) {
         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 MariadbAnalyzeStatement) {
         return StatementType.analyze;
      } else if (statement instanceof MariadbCheckTableStatement) {
         return StatementType.checkTable;
      } else if (statement instanceof MariadbChecksumTableStatement) {
         return StatementType.checkSumTable;
      } else if (statement instanceof MariadbOptimizeStatement) {
         return StatementType.optimize;
      } else if (statement instanceof MariadbRepairTableStatement) {
         return StatementType.repairTable;
      } else if (statement instanceof MariadbShowColumnStatement) {
         return StatementType.showColumn;
      } else if (statement instanceof MariadbShowCreateTableStatement) {
         return StatementType.showCreateTable;
      } else if (statement instanceof SQLShowIndexesStatement) {
         return StatementType.showIndex;
      } else if (statement instanceof MariadbShowOpenTablesStatement) {
         return StatementType.showOpenTables;
      } else if (statement instanceof MariadbFlushStatement) {
         return StatementType.flush;
      } else if (statement instanceof SQLLoadIndexIntoCacheStatement) {
         return StatementType.loadIndexIntoCache;
      } else {
         return statement instanceof MariadbCacheIndexStatement ? 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.mariadb);
      WhereVisitor visitor = new WhereVisitor();
      visitor.perform(statements);
      return visitor.getWheres();
   }

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