package com.chenyang.nse.bussiness.webtools.service.core.impl;

import com.chenyang.nse.bussiness.entity.orm.table.core.TCoreDatasourceSchema;
import com.chenyang.nse.bussiness.service.core.DataSystemService;
import com.chenyang.nse.bussiness.webtools.entity.db.ColumnInfo;
import com.chenyang.nse.bussiness.webtools.entity.db.IndexInfo;
import com.chenyang.nse.bussiness.webtools.entity.vo.ComboboxVO;
import com.chenyang.nse.bussiness.webtools.entity.vo.DBTableVO;
import com.chenyang.nse.bussiness.webtools.entity.vo.DatasystemVO;
import com.chenyang.nse.bussiness.webtools.entity.vo.MviewVO;
import com.chenyang.nse.bussiness.webtools.entity.vo.ProcedureVO;
import com.chenyang.nse.bussiness.webtools.entity.vo.SequenceVO;
import com.chenyang.nse.bussiness.webtools.entity.vo.SynonymsVO;
import com.chenyang.nse.bussiness.webtools.entity.vo.TableVO;
import com.chenyang.nse.bussiness.webtools.entity.vo.ViewVO;
import com.chenyang.nse.bussiness.webtools.enumeration.EdbType;
import com.chenyang.nse.bussiness.webtools.service.core.WebToolsDataSystemService;
import com.chenyang.nse.bussiness.webtools.tools.jdbc.JdbcTool;
import com.chenyang.nse.bussiness.webtools.tools.redis.CacheUtil;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class WebToolsDataSystemServiceImpl implements WebToolsDataSystemService {
   private static final String Link_character = "_";
   private static final Logger ddmauditLogger = LoggerFactory.getLogger("ddmauditLogger");
   private static final Logger operationLogger = LoggerFactory.getLogger("operationLogger");
   @Autowired
   private DataSystemService dataSystemService;

   public List<SequenceVO> querySequenceAttr(DatasystemVO datasystem) throws Exception {
      String dbType = datasystem.getDbtype();
      new ArrayList();
      String defaultSchema = "";
      if (datasystem.getDbtype().equals(EdbType.ORACLE.getDbcode())) {
         defaultSchema = datasystem.getUsername();
      } else {
         defaultSchema = datasystem.getDbservername();
      }

      Connection conn = null;
      if (CacheUtil.exists(genCacheKey(datasystem))) {
         conn = (Connection)CacheUtil.getCacheValue(genCacheKey(datasystem));
      }

      if (conn != null) {
         List<SequenceVO> result = JdbcTool.querySequenceAttr(conn, datasystem.getSequencename(), datasystem.getSchema());
         return result;
      } else {
         throw new Exception("连接数据库失败！");
      }
   }

   public List<ComboboxVO> querySequences(DatasystemVO datasystem) throws Exception {
      String dbType = datasystem.getDbtype();
      List<ComboboxVO> result = new ArrayList();
      Connection conn = null;
      if (CacheUtil.exists(genCacheKey(datasystem))) {
         conn = (Connection)CacheUtil.getCacheValue(genCacheKey(datasystem));
      }

      if (conn == null) {
         throw new Exception("连接数据库失败！");
      } else {
         for(String schemaname : JdbcTool.querySequences(conn, datasystem.getSchema())) {
            ComboboxVO comboboxVO = new ComboboxVO(schemaname);
            result.add(comboboxVO);
         }

         return result;
      }
   }

   public List<ComboboxVO> queryShemas(DatasystemVO datasystem) throws Exception {
      String dbType = datasystem.getDbtype();
      List<ComboboxVO> result = new ArrayList();
      if ("MONGODB".equals(dbType)) {
         String ip = datasystem.getDbip();
         String username = datasystem.getUsername();
         String port = datasystem.getDbport();
         String databaseName = datasystem.getDbservername();
         String newSchema = datasystem.getPassword();
      } else {
         String defaultSchema = "";
         if (datasystem.getDbtype().equals(EdbType.ORACLE.getDbcode())) {
            defaultSchema = datasystem.getUsername();
         } else {
            defaultSchema = datasystem.getDbservername();
         }

         Connection conn = null;
         if (CacheUtil.exists(genCacheKey(datasystem))) {
            conn = (Connection)CacheUtil.getCacheValue(genCacheKey(datasystem));
         }

         if (conn == null) {
            throw new Exception("连接数据库失败！");
         }

         List<String> schema = JdbcTool.getDbSchemas(conn);
         List<TCoreDatasourceSchema> schemas = this.dataSystemService.querySchemas(datasystem.getProjectid(), datasystem.getDatasystemid());
         List<String> newSchema = (List)schemas.stream().map(TCoreDatasourceSchema::getSchemaname).collect(Collectors.toList());

         for(String schemaname : schema) {
            ComboboxVO comboboxVO = new ComboboxVO(schemaname);
            if (schemaname.equalsIgnoreCase(defaultSchema)) {
               comboboxVO.setFlag("1");
            }

            if (newSchema.contains(schemaname)) {
               result.add(comboboxVO);
            }
         }
      }

      return result;
   }

   public Connection getConnectionByDataSystemId(DatasystemVO datasystem) {
      try {
         String dbcode = datasystem.getDbtype();
         if (EdbType.KAFKA.getDbname().equalsIgnoreCase(dbcode)) {
            return null;
         } else {
            String ip = datasystem.getDbip();
            String port = datasystem.getDbport();
            String servername = datasystem.getDbservername();
            String server = datasystem.getServername();
            String url = "";
            switch (datasystem.getDbtype()) {
               case "INFORMIX":
                  url = EdbType.getUrlByEdbcode(dbcode, ip, port, servername, server);
                  break;
               case "TERADATA":
                  url = EdbType.getUrlByEdbcode(dbcode, ip, port, servername, server, datasystem.getPagecode());
                  break;
               default:
                  url = EdbType.getUrlByEdbcode(dbcode, ip, port, servername);
            }

            String username = datasystem.getUsername();
            String password = datasystem.getPassword();
            String driver = EdbType.getEdbTypeByDbcode(dbcode).getDbdriver();
            if ("HIVE".equals(datasystem.getDbtype()) && "on".equals(datasystem.getIskerberos())) {
               System.setProperty("java.security.krb5.conf", datasystem.getXmlpath() + "/krb5.conf");
               Connection conn = JdbcTool.getKerberosConn(url + ";principal=" + datasystem.getPrincipal(), driver, datasystem.getLoginprincipal(), datasystem.getXmlpath());
               return conn;
            } else if (dbcode.equals("RAPIDSDB")) {
               Connection conn = JdbcTool.getConnection(driver, url, username, "");
               return conn;
            } else {
               Connection conn = JdbcTool.getConnection(driver, url, username, password);
               return conn;
            }
         }
      } catch (Exception var12) {
         return null;
      }
   }

   public List<DBTableVO> queryTablename(DatasystemVO datasystem) {
      String datasystemid = datasystem.getDataSystemId();
      String schema = datasystem.getSchema();
      List<DBTableVO> list = new ArrayList();
      if ("MONGODB".equals(datasystem.getDbtype())) {
         String ip = datasystem.getDbip();
         String username = datasystem.getUsername();
         String port = datasystem.getDbport();
         String databaseName = datasystem.getDbservername();
         String passwd = datasystem.getPassword();

         try {
            if (username != null && "".equals(username)) {
            }
         } catch (Exception e) {
            e.printStackTrace();
         }
      } else {
         Connection conn = null;
         if (CacheUtil.exists(genCacheKey(datasystem))) {
            conn = (Connection)CacheUtil.getCacheValue(genCacheKey(datasystem));
         }

         if (conn != null) {
            for(String str : JdbcTool.getAllTableName(conn, schema)) {
               DBTableVO v = new DBTableVO();
               v.setTablename(str);
               list.add(v);
            }
         }
      }

      return list;
   }

   public List<String> queryView(DatasystemVO datasystem) {
      String schema = datasystem.getSchema();
      List<String> list = new ArrayList();
      Connection conn = null;
      if (CacheUtil.exists(genCacheKey(datasystem))) {
         conn = (Connection)CacheUtil.getCacheValue(genCacheKey(datasystem));
      }

      if (conn != null) {
         list = JdbcTool.getAllViewName(conn, schema);
      }

      return list;
   }

   public List<String> querySynonym(DatasystemVO datasystem) {
      String datasystemid = datasystem.getDataSystemId();
      String schema = datasystem.getSchema();
      List<String> list = new ArrayList();
      Connection conn = null;
      if (CacheUtil.exists(genCacheKey(datasystem))) {
         conn = (Connection)CacheUtil.getCacheValue(genCacheKey(datasystem));
      }

      if (conn != null) {
         list = JdbcTool.getAllSynonymName(conn, schema);
      }

      return list;
   }

   public List<SynonymsVO> querySynonymAttr(DatasystemVO datasystem) throws Exception {
      String dbType = datasystem.getDbtype();
      new ArrayList();
      Connection conn = null;
      if (CacheUtil.exists(genCacheKey(datasystem))) {
         conn = (Connection)CacheUtil.getCacheValue(genCacheKey(datasystem));
      }

      if (conn != null) {
         List<SynonymsVO> result = JdbcTool.querySynonymAttr(conn, datasystem.getSynonymname(), datasystem.getSchema());
         return result;
      } else {
         throw new Exception("连接数据库失败！");
      }
   }

   public List<ViewVO> queryViewDeclare(DatasystemVO datasystem) throws Exception {
      String dbType = datasystem.getDbtype();
      new ArrayList();
      Connection conn = null;
      if (CacheUtil.exists(genCacheKey(datasystem))) {
         conn = (Connection)CacheUtil.getCacheValue(genCacheKey(datasystem));
      }

      if (conn != null) {
         List<ViewVO> result = JdbcTool.queryViewDeclare(conn, datasystem.getViewname(), datasystem.getSchema());
         return result;
      } else {
         throw new Exception("连接数据库失败！");
      }
   }

   public List<ColumnInfo> queryViewColumn(DatasystemVO datasystem) throws Exception {
      String dbType = datasystem.getDbtype();
      new ArrayList();
      String schema = datasystem.getSchema();
      String table_name = datasystem.getViewname();
      Connection conn = null;
      if (CacheUtil.exists(genCacheKey(datasystem))) {
         conn = (Connection)CacheUtil.getCacheValue(genCacheKey(datasystem));
      }

      if (conn != null) {
         List<ColumnInfo> allColumns = JdbcTool.getAllColumnInfo(conn, schema.toUpperCase(), table_name.toUpperCase());
         if (dbType.equals("GREENPLUM")) {
            JdbcTool.getColumnInfoVO(conn, schema, table_name);
         }

         return allColumns;
      } else {
         throw new Exception("连接数据库失败！");
      }
   }

   public List<IndexInfo> queryTableIndex(DatasystemVO datasystem) throws Exception {
      List<IndexInfo> indexInfo = null;
      String dbType = datasystem.getDbtype();
      new ArrayList();
      String schema = datasystem.getSchema();
      String table_name = datasystem.getViewname();
      Connection conn = null;
      if (CacheUtil.exists(genCacheKey(datasystem))) {
         conn = (Connection)CacheUtil.getCacheValue(genCacheKey(datasystem));
      }

      if (conn != null) {
         if (!dbType.equals(EdbType.HIVE.getDbname())) {
            indexInfo = IndexInfo.getIndexInfoByConnection(conn, schema, table_name);
         }

         return indexInfo;
      } else {
         throw new Exception("连接数据库失败！");
      }
   }

   public List<MviewVO> queryMViewAttr2Declare(DatasystemVO datasystem) throws Exception {
      String dbType = datasystem.getDbtype();
      new ArrayList();
      new ArrayList();
      Connection conn = null;
      if (CacheUtil.exists(genCacheKey(datasystem))) {
         conn = (Connection)CacheUtil.getCacheValue(genCacheKey(datasystem));
      }

      List<MviewVO> attrList = JdbcTool.queryMViewAttr(conn, datasystem.getViewname(), datasystem.getSchema());
      if (conn != null) {
         List<MviewVO> result = JdbcTool.queryMViewDeclare(conn, datasystem.getViewname(), datasystem.getSchema());
         if (result.size() > 0) {
            this.parse((MviewVO)result.get(0), attrList);
         }

         return result;
      } else {
         throw new Exception("连接数据库失败！");
      }
   }

   private void parse(MviewVO vo, List<MviewVO> attrList) {
      String text = vo.getText();
      Matcher m = Pattern.compile(".*\\s+REFRESH\\s+FORCE\\s+ON\\s+(\\S+?)($|;|\\s+.+)").matcher(text);
      if (m.find() && 2 == m.groupCount()) {
         System.out.println("[" + m.group(1) + "]");
         vo.setRefreshMode(m.group(1));
      }

      Matcher m2 = Pattern.compile(".*\\s+BUILD\\s+(\\S+?)($|;|\\s+.+)").matcher(text);
      if (m2.find() && 2 == m2.groupCount()) {
         System.out.println("[" + m2.group(1) + "]");
         vo.setBuildMode(m2.group(1));
      }

      vo.setRewrite("GENERAL");
      vo.setRefreshType("COMPLETE");
      vo.setDisableState("FRESH");
      vo.setQuickRefresh("NO");
      if (attrList.size() > 0) {
         vo.setContainer(((MviewVO)attrList.get(0)).getContainer());
         vo.setRefreshMethod(((MviewVO)attrList.get(0)).getRefreshMethod());
         vo.setRefreshDate(((MviewVO)attrList.get(0)).getRefreshDate());
      }

   }

   public static void main(String[] args) {
      String text = "CREATE MATERIALIZED VIEW \"EAST\".\"MV_MATERIALIZED_TEST\" (\"USERID\", \"USERNAME\", \"IDCODE\", \"PHONE\", \"DEPTID\", \"ADDRESS\", \"PARDEPTID\")\n  ORGANIZATION HEAP PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 \n NOCOMPRESS LOGGING\n  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645\n  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1\n  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)\n  TABLESPACE \"EASTAIR\" \n  BUILD IMMEDIATE\n  USING INDEX \n  REFRESH FORCE ON DEMAND START WITH sysdate+0 NEXT to_date( concat (to_char( sysdate + 1 , 'dd-mm-yyyy' ), '10:25:00' ), 'dd-mm-yyyy hh24:mi:ss' )\n  USING DEFAULT LOCAL ROLLBACK SEGMENT\n  USING ENFORCED CONSTRAINTS DISABLE QUERY REWRITE\n  AS select  *  from  east.at_person;\n\nCOMMENT ON MATERIALIZED VIEW EAST.MV_MATERIALIZED_TEST IS 'snapshot table for snapshot EAST.MV_MATERIALIZED_TEST';";
      Matcher m3 = Pattern.compile(".*\\s+IS\\s+('.*?')($|;|\\s+.+)").matcher(text);
      if (m3.find() && 2 == m3.groupCount()) {
         System.out.println("[" + m3.group(1) + "]");
         System.out.println(m3.group(1));
      }

   }

   public TableVO queryTableComment2Space(DatasystemVO datasystem) throws Exception {
      TableVO result = new TableVO();
      String dbType = datasystem.getDbtype();
      String tableComments = "";
      String tableSpace = "";
      Connection conn = null;
      if (CacheUtil.exists(genCacheKey(datasystem))) {
         conn = (Connection)CacheUtil.getCacheValue(genCacheKey(datasystem));
      }

      if (conn != null) {
         tableComments = JdbcTool.queryTableComments(conn, datasystem.getViewname(), datasystem.getSchema());
         tableSpace = JdbcTool.queryTableSpace(conn, datasystem.getViewname(), datasystem.getSchema());
         result.setTableComments(tableComments == null ? "" : tableComments);
         result.setTableSpace(tableSpace);
         result.setTableName(datasystem.getViewname());
         return result;
      } else {
         throw new Exception("连接数据库失败！");
      }
   }

   public ViewVO queryViewComments(DatasystemVO datasystem) throws Exception {
      ViewVO result = new ViewVO();
      String dbType = datasystem.getDbtype();
      String comments = "";
      Connection conn = null;
      if (CacheUtil.exists(genCacheKey(datasystem))) {
         conn = (Connection)CacheUtil.getCacheValue(genCacheKey(datasystem));
      }

      if (conn != null) {
         comments = JdbcTool.queryViewComments(conn, datasystem.getViewname(), datasystem.getSchema());
         result.setComments(comments == null ? "" : comments);
         result.setViewname(datasystem.getViewname());
         return result;
      } else {
         throw new Exception("连接数据库失败！");
      }
   }

   public List<String> queryProcedures(DatasystemVO datasystem) {
      String datasystemid = datasystem.getDataSystemId();
      String schema = datasystem.getSchema();
      List<String> list = new ArrayList();
      Connection conn = null;
      if (CacheUtil.exists(genCacheKey(datasystem))) {
         conn = (Connection)CacheUtil.getCacheValue(genCacheKey(datasystem));
      }

      if (conn != null) {
         list = JdbcTool.queryProcedures(conn, schema);
      }

      return list;
   }

   public List<String> queryFunctions(DatasystemVO datasystem) {
      String datasystemid = datasystem.getDataSystemId();
      String schema = datasystem.getSchema();
      List<String> list = new ArrayList();
      Connection conn = null;
      if (CacheUtil.exists(genCacheKey(datasystem))) {
         conn = (Connection)CacheUtil.getCacheValue(genCacheKey(datasystem));
      }

      if (conn != null) {
         list = JdbcTool.queryFunctions(conn, schema);
      }

      return list;
   }

   public List<String> queryMviewList(DatasystemVO datasystem) {
      String datasystemid = datasystem.getDataSystemId();
      String schema = datasystem.getSchema();
      List<String> list = new ArrayList();
      Connection conn = null;
      if (CacheUtil.exists(genCacheKey(datasystem))) {
         conn = (Connection)CacheUtil.getCacheValue(genCacheKey(datasystem));
      }

      if (conn != null) {
         list = JdbcTool.queryMviewList(conn, schema);
      }

      return list;
   }

   public ProcedureVO queryProcedureAttr2Declare(DatasystemVO datasystem) throws Exception {
      String dbType = datasystem.getDbtype();
      new ArrayList();
      new ProcedureVO();
      Connection conn = null;
      if (CacheUtil.exists(genCacheKey(datasystem))) {
         conn = (Connection)CacheUtil.getCacheValue(genCacheKey(datasystem));
      }

      ProcedureVO procedureVO = JdbcTool.queryProcedureParam(conn, datasystem.getViewname(), datasystem.getSchema());
      if (conn != null) {
         List<ProcedureVO> result = JdbcTool.queryProcedureDeclare(conn, datasystem.getViewname(), datasystem.getSchema());
         if (result.size() > 0) {
            procedureVO.setText(((ProcedureVO)result.get(0)).getText());
         }

         return procedureVO;
      } else {
         throw new Exception("连接数据库失败！");
      }
   }

   public ProcedureVO queryFunctionAttr2Declare(DatasystemVO datasystem) throws Exception {
      String dbType = datasystem.getDbtype();
      new ArrayList();
      new ProcedureVO();
      Connection conn = null;
      if (CacheUtil.exists(genCacheKey(datasystem))) {
         conn = (Connection)CacheUtil.getCacheValue(genCacheKey(datasystem));
      }

      ProcedureVO procedureVO = JdbcTool.queryFunctionParam(conn, datasystem.getViewname(), datasystem.getSchema());
      if (conn != null) {
         List<ProcedureVO> result = JdbcTool.queryFunctionDeclare(conn, datasystem.getViewname(), datasystem.getSchema());
         if (result.size() > 0) {
            procedureVO.setText(((ProcedureVO)result.get(0)).getText());
         }

         return procedureVO;
      } else {
         throw new Exception("连接数据库失败！");
      }
   }

   private static String genCacheKey(DatasystemVO datasource) {
      return datasource.getFingerprint() + "_" + datasource.getDbip() + "_" + datasource.getDbport() + "_" + datasource.getUsername();
   }
}
