package com.chenyang.nse.bussiness.service.core.udf;

import com.chenyang.nse.bussiness.dao.table.core.encryption.TCoreEncryptionTypeFieldDao;
import com.chenyang.nse.bussiness.entity.orm.table.core.TCoreDatasystem;
import com.chenyang.nse.bussiness.entity.vo.encyption.EncryptionConfigVO;
import com.chenyang.nse.bussiness.entity.vo.maskingtask.ColumnInfoVO;
import com.chenyang.nse.bussiness.service.core.TdataProjectService;
import com.chenyang.nse.bussiness.service.core.encryption.EncryptionConfigService;
import com.chenyang.nse.bussiness.tools.jdbc.JdbcTool;
import com.chenyang.nse.bussiness.tools.strategy.StrategyData;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Service;

@Service
public class OracleUdfService extends UdfService {
   private Connection connection = null;
   public String type = "oracle";

   public OracleUdfService(TdataProjectService tdataProjectService, EncryptionConfigService encryptionConfigService, TCoreEncryptionTypeFieldDao tCoreEncryptionTypeFieldDao, StrategyData strategyData) {
      super(tdataProjectService, encryptionConfigService, tCoreEncryptionTypeFieldDao, strategyData);
   }

   public String alterTableName(TCoreDatasystem tCoreDatasystem, String schemaName, String tableName, String udfTableName) {
      String schemaTable = "\"" + schemaName + "\".\"" + tableName + "\"";
      String udfTable = "\"" + udfTableName + "\"";

      try {
         this.connection = JdbcTool.getConnection(tCoreDatasystem);
         Statement statement = this.connection.createStatement();
         String alterNameSql = "alter table " + schemaTable + " rename to " + udfTable;
         String createEncFuntion = "CREATE OR REPLACE FUNCTION ENC_DATA_JAVA(ruleId VARCHAR2,source VARCHAR2) RETURN VARCHAR2 AS LANGUAGE JAVA NAME 'com.ghca.Enc.encData(java.lang.String,java.lang.String) return String';";
         String createDecFuntion = "CREATE OR REPLACE FUNCTION DEC_DATA_JAVA(ruleId VARCHAR2,source VARCHAR2) RETURN VARCHAR2 AS LANGUAGE JAVA NAME 'com.ghca.Enc.decData(java.lang.String,java.lang.String) return String';";
         String grant = "call dbms_java.grant_permission( '" + schemaName + "', 'SYS:java.security.SecurityPermission', 'insertProvider.BC', '' ); call dbms_java.grant_permission( '" + schemaName + "', 'SYS:java.security.SecurityPermission', 'putProviderProperty.BC', '' ); call dbms_java.grant_permission( '" + schemaName + "', 'SYS:java.lang.RuntimePermission', 'setFactory', '' ); call dbms_java.grant_permission( '" + schemaName + "', 'SYS:javax.net.ssl.SSLPermission', 'setHostnameVerifier', '' ); call dbms_java.grant_permission( '" + schemaName + "', 'SYS:java.lang.reflect.ReflectPermission', 'suppressAccessChecks', '' ); call dbms_java.grant_permission( '" + schemaName + "', 'SYS:java.lang.RuntimePermission', 'accessDeclaredMembers', '' ); ";
         statement.executeUpdate(alterNameSql);
         statement.executeUpdate(createEncFuntion);
         statement.executeUpdate(createDecFuntion);
         statement.executeUpdate(grant);
         return "ok";
      } catch (SQLException e) {
         return e.getMessage();
      }
   }

   public boolean isInited(String dataSystemId, String schemaName, String tableName) {
      if (this.isInited(tableName)) {
         return true;
      } else {
         String udfTableName = this.getUdfTable(tableName);
         String sql = "select * from all_tables where OWNER = '" + schemaName + "' and TABLE_NAME = '" + udfTableName + "'";
         TCoreDatasystem tCoreDatasystem = this.tdataProjectService.selectOneProDataSource(dataSystemId);
         this.connection = JdbcTool.getConnection(tCoreDatasystem);
         Statement statement = null;

         try {
            statement = this.connection.createStatement();
            ResultSet res = statement.executeQuery(sql);
            if (res.next()) {
               boolean var9 = true;
               return var9;
            } else {
               return false;
            }
         } catch (SQLException e) {
            throw new RuntimeException(e);
         } finally {
            ;
         }
      }
   }

   public boolean isFinished(String datasystemId, String schme, String tableName) {
      TCoreDatasystem tCoreDatasystem = this.tdataProjectService.selectOneProDataSource(datasystemId);
      this.connection = JdbcTool.getConnection(tCoreDatasystem);

      try {
         this.connection = JdbcTool.getConnection(tCoreDatasystem);
         Statement statement = this.connection.createStatement();
         String alterNameSql = "SELECT * FROM all_views where OWNER = '" + schme + "' and VIEW_NAME = '" + this.getSourceTable(tableName) + "'";
         ResultSet res = statement.executeQuery(alterNameSql);
         return res.next();
      } catch (SQLException var8) {
         throw new RuntimeException("查询udf完成状态异常");
      }
   }

   public String finish(EncryptionConfigVO vo) {
      String projectId = vo.getProjectId();
      String datasystemId = vo.getDatasystem_id();
      String schemaName = vo.getSchema();
      String tableName = vo.getTable_name();
      TCoreDatasystem tCoreDatasystem = this.tdataProjectService.selectOneProDataSource(datasystemId);
      String rulePrefix = tCoreDatasystem.getDbip() + "_" + tCoreDatasystem.getDbport() + "_" + tCoreDatasystem.getUsername() + "_" + tableName + "_";
      List<ColumnInfoVO> originList = this.encryptionConfigService.queryOriginalList(vo);
      Iterator<ColumnInfoVO> iterator = originList.iterator();

      while(iterator.hasNext()) {
         ColumnInfoVO item = (ColumnInfoVO)iterator.next();
         if (item.getColumnname().contains("_copy")) {
            iterator.remove();
         }
      }

      List<Map<String, String>> encryptionList = this.encryptionConfigService.queryEncryptionList(vo);
      Map<String, String> encryptionMap = new HashMap();

      for(int j = 0; j < encryptionList.size(); ++j) {
         if (((String)((Map)encryptionList.get(j)).get("flag")).equals("5")) {
            String columnName = (String)((Map)encryptionList.get(j)).get("fieldName");
            encryptionMap.put(columnName, (rulePrefix + columnName).toLowerCase());
         }
      }

      String createViewSql = this.getCreateViewSql(schemaName, tableName, originList, encryptionMap);
      String createTriggerSql = this.getCreateTriggerSql(schemaName, tableName, originList, encryptionMap);

      try {
         this.connection = JdbcTool.getConnection(tCoreDatasystem);
         Statement statement = this.connection.createStatement();
         statement.executeUpdate(createViewSql);
         statement.executeUpdate(createTriggerSql);
         return "ok";
      } catch (SQLException e) {
         return e.getMessage();
      }
   }

   public String getCreateTriggerSql(String schemaName, String tableName, List<ColumnInfoVO> originList, Map<String, String> encryptionMap) {
      String viewName = this.getSourceTable(tableName);
      String schameView = "\"" + schemaName + "\".\"" + viewName + "\"";
      String schameTable = "\"" + schemaName + "\".\"" + tableName + "\"";
      String triggerName = schemaName + ".\"" + viewName + "_udf_encData\"";
      String declare = "";
      String insert = " ( ";
      String update = "";
      String values = " values( ";
      String isNull = "";
      String where = "";

      for(int i = 0; i < originList.size(); ++i) {
         ColumnInfoVO column = (ColumnInfoVO)originList.get(i);
         String columnName = "\"" + column.getColumnname() + "\"";
         insert = insert + columnName;
         String valueName = ":NEW.\"" + column.getColumnname() + "\"";
         update = update + columnName + " = ";
         if (column.getColumndef() != null) {
            valueName = "d_" + column.getColumnname();
            declare = declare + valueName + " " + column.getTypename();
            if (column.getColumnsize() != null) {
               declare = declare + " (" + column.getColumnsize() + ") ";
            }

            declare = declare + " := :NEW." + columnName + "; ";
            isNull = isNull + "if (:NEW." + columnName + " is null) then ";
            isNull = isNull + valueName + " := " + column.getColumndef() + "; ";
            isNull = isNull + " end if ; ";
         }

         String rule = (String)encryptionMap.get(column.getColumnname());
         if (rule != null) {
            valueName = "ENC_DATA_JAVA('" + rule + "'," + valueName + ")";
         }

         values = values + valueName;
         update = update + valueName;
         if (i != originList.size() - 1) {
            values = values + ",";
            insert = insert + ",";
            update = update + ",";
         }

         if (column.getPrimarykey().equals("1")) {
            where = " where " + columnName + " = :NEW." + columnName;
         }
      }

      insert = insert + " )";
      values = values + " )";
      String sql = "CREATE OR REPLACE TRIGGER " + triggerName + " instead of INSERT OR UPDATE ON " + schameView + " FOR EACH ROW ";
      sql = sql + " DECLARE " + declare;
      sql = sql + " BEGIN ";
      sql = sql + " if inserting then ";
      sql = sql + isNull;
      sql = sql + " insert into " + schameTable;
      sql = sql + insert + values + ";";
      sql = sql + " end if;";
      sql = sql + " if updating then ";
      sql = sql + " update " + schameTable + " set " + update + where + ";";
      sql = sql + " end if;";
      sql = sql + " END;";
      return sql;
   }

   public String getCreateViewSql(String schemaName, String tableName, List<ColumnInfoVO> originList, Map<String, String> encryptionMap) {
      String viewName = this.getSourceTable(tableName);
      String sql = "CREATE or replace VIEW \"" + schemaName + "\".\"" + viewName + "\" AS SELECT ";

      for(int i = 0; i < originList.size(); ++i) {
         ColumnInfoVO column = (ColumnInfoVO)originList.get(i);
         String columnName = "\"" + column.getColumnname() + "\"";
         if (!columnName.contains("_copy")) {
            String rule = (String)encryptionMap.get(column.getColumnname());
            if (rule != null) {
               columnName = " DEC_DATA_JAVA('" + rule + "'," + columnName + ") AS " + columnName;
            }

            sql = sql + "" + columnName;
            if (i != originList.size() - 1) {
               sql = sql + ",";
            }
         }
      }

      sql = sql + " FROM \"" + tableName + "\"";
      return sql;
   }

   public String getType() {
      return "oracle";
   }
}
