package util.sqlparse.visitor.common;

import bean.Column;
import bean.DataBase;
import bean.Table;
import bean.View;
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.SQLCreateViewStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.stat.TableStat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import util.log.SQLLogger;
import util.sqlparse.visitor.common.bean.TableInfo;
import util.sqlparse.visitor.common.memo.TableMemo;
import util.sqlparse.visitor.common.names.NameWrapper;

public class Context {
   private DataBase dataBase;
   private String schema;
   public TableStat.Mode sqlType;
   private static Map<String, Map<String, SQLSelect>> cacheSchemaViewMap;
   private final Map<String, TableInfo> tableMap;
   private String dbType;
   private static Set<String> errorViews = new HashSet();
   private static ReadWriteLock errorLock = new ReentrantReadWriteLock(true);
   private NameWrapper nameWrapper;

   public Context() {
      cacheSchemaViewMap = new HashMap();
      this.tableMap = new HashMap();
   }

   public void initialize(DataBase db, String sch, String dbType) {
      this.dataBase = db;
      this.schema = sch;
      this.dbType = dbType;
      this.nameWrapper = NameWrapper.create(DbType.of(dbType), this.dataBase.simpleCache);
   }

   private SQLSelect parseView(View view) {
      if (view.getCreate_sql() != null && view.getCreate_sql().length() > 0) {
         try {
            List<SQLStatement> statements = SQLUtils.parseStatements(view.getCreate_sql(), this.dbType);
            if (statements.size() > 0) {
               SQLStatement statement = (SQLStatement)statements.get(0);
               if (statement instanceof SQLCreateViewStatement) {
                  SQLCreateViewStatement vst = (SQLCreateViewStatement)statement;
                  SQLSelect select = vst.getSubQuery();
                  return select;
               }

               if (statement instanceof SQLSelectStatement) {
                  SQLSelectStatement selectStatement = (SQLSelectStatement)statement;
                  SQLSelect select = selectStatement.getSelect();
                  return select;
               }
            }
         } catch (Exception e) {
            SQLLogger.log(e.getMessage());
         }
      }

      return null;
   }

   public List<Column> getColumns(String schemaName, String tableName) {
      if (this.dataBase == null) {
         return new ArrayList();
      } else {
         NameWrapper wrapper = NameWrapper.create(DbType.of(this.dataBase.getDbType()), this.dataBase.simpleCache);
         Table table = wrapper.getTable(schemaName, tableName);
         return (List<Column>)(table != null && table.getColumnList().size() > 0 ? table.getColumnList() : new ArrayList());
      }
   }

   public DataBase getDataBase() {
      return this.dataBase;
   }

   public void setDataBase(DataBase dataBase) {
      this.dataBase = dataBase;
   }

   public String getSchema() {
      return this.schema;
   }

   public void setSchema(String schema) {
      this.schema = schema;
   }

   public List<TableInfo> getTables() {
      return new ArrayList(this.tableMap.values());
   }

   public Map<String, TableInfo> getTableMap() {
      return this.tableMap;
   }

   public SQLSelect getView(String schema, String name) {
      try {
         errorLock.readLock().lock();
         Map<String, SQLSelect> viewMap = (Map)cacheSchemaViewMap.get(schema);
         if (viewMap != null) {
            SQLSelect var4 = (SQLSelect)viewMap.get(name);
            return var4;
         }
      } finally {
         errorLock.readLock().unlock();
      }

      View view = this.nameWrapper.getView(schema, name);
      if (view != null && view.getCreate_sql() != null && !view.getCreate_sql().isEmpty()) {
         SQLSelect sqlSelect = this.parseView(view);

         SQLSelect var6;
         try {
            errorLock.writeLock().lock();
            Map<String, SQLSelect> map = (Map)cacheSchemaViewMap.get(schema);
            if (map == null) {
               map = new HashMap();
               cacheSchemaViewMap.put(schema, map);
            }

            map.put(name, sqlSelect);
            var6 = sqlSelect;
         } finally {
            errorLock.writeLock().unlock();
         }

         return var6;
      } else {
         return null;
      }
   }

   public void append(TableMemo tableMemo) {
      tableMemo.atom = true;
      String name = tableMemo.getAtomName();
      if (!this.tableMap.containsKey(name)) {
         TableInfo table = new TableInfo();
         table.setTable(tableMemo);
         this.tableMap.put(name, table);
         table.addMemo(tableMemo);
      } else {
         TableInfo table = (TableInfo)this.tableMap.get(name);
         table.addMemo(tableMemo);
      }

   }

   public String getDbType() {
      return this.dbType;
   }
}
