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

import com.chenyang.nse.bussiness.dao.core.DataMapDao;
import com.chenyang.nse.bussiness.dao.table.core.TCoreDatasystemDao;
import com.chenyang.nse.bussiness.dao.table.core.datamap.TCoreDatamapColumnDao;
import com.chenyang.nse.bussiness.dao.table.core.datamap.TCoreDatamapDao;
import com.chenyang.nse.bussiness.dao.table.core.datamap.TCoreDatamapForeignkeyDao;
import com.chenyang.nse.bussiness.dao.table.core.datamap.TCoreDatamapTableDao;
import com.chenyang.nse.bussiness.dao.table.core.datamap.TCoreDatamapTablealiasDao;
import com.chenyang.nse.bussiness.dao.table.core.datamap.TCoreDatamapTablerelationDao;
import com.chenyang.nse.bussiness.dao.table.core.datamap.TCoreDatamapUsermapDao;
import com.chenyang.nse.bussiness.dao.table.core.masking.TCoreMaskingTableDao;
import com.chenyang.nse.bussiness.dao.table.core.masking.TCoreMaskingTablecolumnDao;
import com.chenyang.nse.bussiness.dao.table.core.masking.TCoreMaskingTaskDao;
import com.chenyang.nse.bussiness.entity.db.ColumnInfo;
import com.chenyang.nse.bussiness.entity.db.ForeignKeyInfo;
import com.chenyang.nse.bussiness.entity.db.TableInfo;
import com.chenyang.nse.bussiness.entity.orm.table.core.TCoreDatasystem;
import com.chenyang.nse.bussiness.entity.orm.table.core.datamap.TCoreDatamap;
import com.chenyang.nse.bussiness.entity.orm.table.core.datamap.TCoreDatamapColumn;
import com.chenyang.nse.bussiness.entity.orm.table.core.datamap.TCoreDatamapTable;
import com.chenyang.nse.bussiness.entity.orm.table.core.datamap.TCoreDatamapTablealias;
import com.chenyang.nse.bussiness.entity.orm.table.core.datamap.TCoreDatamapTablerelation;
import com.chenyang.nse.bussiness.entity.orm.table.core.datamap.TCoreDatamapUsermap;
import com.chenyang.nse.bussiness.entity.orm.table.core.masking.TCoreMaskingTable;
import com.chenyang.nse.bussiness.entity.orm.table.core.masking.TCoreMaskingTablecolumn;
import com.chenyang.nse.bussiness.entity.orm.table.core.masking.TCoreMaskingTask;
import com.chenyang.nse.bussiness.entity.vo.TreeVO;
import com.chenyang.nse.bussiness.enumeration.EdataSystemGrade;
import com.chenyang.nse.bussiness.enumeration.EdbType;
import com.chenyang.nse.bussiness.enumeration.EmaskingDirection;
import com.chenyang.nse.bussiness.enumeration.EmaskingTaskType;
import com.chenyang.nse.bussiness.service.core.DataMapService;
import com.chenyang.nse.bussiness.tools.jdbc.JdbcTool;
import com.chenyang.nse.bussiness.tools.number.IntegerTool;
import com.chenyang.nse.bussiness.tools.other.ColorTool;
import com.chenyang.nse.bussiness.tools.string.AesTool;
import com.chenyang.nse.bussiness.tools.string.StringTool;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class DataMapServiceImpl implements DataMapService {
   @Autowired
   private TCoreDatasystemDao tCoreDatasystemDao;
   @Autowired
   private TCoreDatamapDao tCoreDatamapDao;
   @Autowired
   private TCoreDatamapTableDao tCoreDatamapTableDao;
   @Autowired
   private TCoreDatamapForeignkeyDao tCoreDatamapForeignkeyDao;
   @Autowired
   private TCoreDatamapColumnDao tCoreDatamapColumnDao;
   @Autowired
   private TCoreDatamapTablerelationDao tCoreDatamapTablerelationDao;
   @Autowired
   private TCoreDatamapUsermapDao tCoreDatamapUsermapDao;
   @Autowired
   private TCoreDatamapTablealiasDao tCoreDatamapTablealiasDao;
   @Autowired
   private TCoreMaskingTaskDao tCoreMaskingTaskDao;
   @Autowired
   private DataMapDao dataMapDao;
   @Autowired
   private TCoreMaskingTableDao tCoreMaskingTableDao;
   @Autowired
   private TCoreMaskingTablecolumnDao tCoreMaskingTablecolumnDao;

   public Connection getConnectionByDataSystemId(String datasystemid) {
      TCoreDatasystem datasystem = (TCoreDatasystem)this.tCoreDatasystemDao.get(datasystemid);
      String dbcode = datasystem.getDbtype();
      String ip = datasystem.getDbip();
      String port = datasystem.getDbport();
      String servername = datasystem.getDbservername();
      String url = EdbType.getUrlByEdbcode(dbcode, ip, port, servername);
      String username = datasystem.getUsername();
      String password = AesTool.decrypt(datasystem.getPassword(), "ghca");
      String driver = EdbType.getEdbTypeByDbcode(dbcode).getDbdriver();
      Connection conn = JdbcTool.getConnection(driver, url, username, password);
      return conn;
   }

   public TCoreDatamap queryDataMapUnique(String datasystemid, String dbschema) {
      TCoreDatamap dataMap = (TCoreDatamap)this.tCoreDatamapDao.queryUnique(new Criterion[]{Restrictions.eq("datasystemid", datasystemid), Restrictions.eq("dbschema", dbschema)});
      return dataMap;
   }

   public void generateDataMap(String datasystemid, String schema) {
      TCoreDatamap dataMap = new TCoreDatamap(datasystemid, schema, new Date());
      this.tCoreDatamapDao.save(dataMap);
      String dataMapId = dataMap.getId();
      TCoreDatasystem dataSystem = (TCoreDatasystem)this.tCoreDatasystemDao.get(datasystemid);
      String url = EdbType.getUrlByEdbcode(dataSystem.getDbtype(), dataSystem.getDbip(), dataSystem.getDbport(), dataSystem.getDbservername());
      Connection conn = JdbcTool.getConnection(EdbType.getEdbTypeByDbcode(dataSystem.getDbtype()).getDbdriver(), url, dataSystem.getUsername(), AesTool.decrypt(dataSystem.getPassword(), "ghca"));

      for(TableInfo tableInfo : JdbcTool.getTableInfoByConnection(conn, schema, (String)null)) {
         TCoreDatamapTable dataMapTable = new TCoreDatamapTable(ColorTool.randomColor(), tableInfo.getTablename(), String.valueOf(IntegerTool.randomInt(-3000, 3000)), String.valueOf(IntegerTool.randomInt(-2000, 2000)), String.valueOf(IntegerTool.randomInt(20, 40)), dataMapId, (String)null, (String)null);
         String tableNote = JdbcTool.queryTableNote(conn, schema, tableInfo.getTablename());
         TCoreDatamapTablealias tableAlias = this.tCoreDatamapTablealiasDao.queryDataMapTableAlias(datasystemid, schema, tableInfo.getTablename());
         if (tableAlias != null) {
            dataMapTable.setByname(tableAlias.getTablebyname());
         }

         dataMapTable.setNote(tableNote);
         this.tCoreDatamapTableDao.save(dataMapTable);

         for(ColumnInfo columnInfo : tableInfo.getColumninfos()) {
            TCoreDatamapColumn dataMapColumn = new TCoreDatamapColumn(dataMapId, columnInfo.getColumnname(), columnInfo.getTypename(), columnInfo.getColumnsize(), dataMapTable.getId());
            dataMapColumn.setNote(columnInfo.getRemarks());
            this.tCoreDatamapColumnDao.save(dataMapColumn);
         }
      }

      List<ForeignKeyInfo> foreignkey = JdbcTool.queryForeignKey(conn, schema);
      if (foreignkey != null && foreignkey.size() != 0) {
         for(ForeignKeyInfo foreignKey : foreignkey) {
            TCoreDatamapTable sourcetable = this.tCoreDatamapTableDao.queryDataMapTable(dataMapId, foreignKey.getPktable());
            TCoreDatamapTable targettable = this.tCoreDatamapTableDao.queryDataMapTable(dataMapId, foreignKey.getFktable());
            if (sourcetable != null && targettable != null) {
               boolean exist = this.tCoreDatamapTablerelationDao.isRelationExist(dataMapId, sourcetable.getId(), targettable.getId());
               if (!exist) {
                  this.tCoreDatamapTablerelationDao.save(new TCoreDatamapTablerelation(sourcetable.getId(), targettable.getId(), "1", dataMapId));
               }
            }
         }

      }
   }

   public void removeDataMap(String datamapid) {
      this.tCoreDatamapTableDao.remove(new Criterion[]{Restrictions.eq("datamapid", datamapid)});
      this.tCoreDatamapForeignkeyDao.remove(new Criterion[]{Restrictions.eq("datamapid", datamapid)});
      this.tCoreDatamapTablerelationDao.remove(new Criterion[]{Restrictions.eq("datamapid", datamapid)});
      this.tCoreDatamapColumnDao.remove(new Criterion[]{Restrictions.eq("datamapid", datamapid)});
      this.tCoreDatamapDao.removeById(datamapid);
   }

   public void removeDataMap(String datasystemid, String schema) {
      TCoreDatamap datamap = this.queryDataMapUnique(datasystemid, schema);
      if (datamap != null) {
         this.removeDataMap(datamap.getId());
      }

   }

   public List<TCoreDatamapTablerelation> queryDataMapTableRelation(String datamapid) {
      List<TCoreDatamapTablerelation> list = this.tCoreDatamapTablerelationDao.queryAll(new Criterion[]{Restrictions.eq("datamapid", datamapid)});
      return list;
   }

   public TCoreDatamapTablealias setTableAlias(String datasystemid, String schema, String table, String alias) {
      TCoreDatamapTablealias tableAlias = this.tCoreDatamapTablealiasDao.queryDataMapTableAlias(datasystemid, schema, table);
      if (tableAlias != null) {
         tableAlias.setTablebyname(alias);
         this.tCoreDatamapTablealiasDao.saveOrUpdate(tableAlias);
         return tableAlias;
      } else {
         tableAlias = new TCoreDatamapTablealias(datasystemid, schema, table, alias);
         this.tCoreDatamapTablealiasDao.save(tableAlias);
         return tableAlias;
      }
   }

   public void synchronizeDataMapTableAlias(TCoreDatamapTablealias tableAlias) {
      TCoreDatamap dataMap = this.queryDataMapUnique(tableAlias.getDatasystemid(), tableAlias.getDbschema());
      if (dataMap != null) {
         TCoreDatamapTable dataMapTable = this.tCoreDatamapTableDao.queryDataMapTable(dataMap.getId(), tableAlias.getTablename());
         if (dataMapTable != null) {
            dataMapTable.setByname(tableAlias.getTablebyname());
            this.tCoreDatamapTableDao.saveOrUpdate(dataMapTable);
         }
      }
   }

   public List<TCoreDatamapTable> queryDataMapTable(String datamapid) {
      List<TCoreDatamapTable> list = this.tCoreDatamapTableDao.queryAll(new Criterion[]{Restrictions.eq("datamapid", datamapid)});
      return list;
   }

   public TCoreDatamapTable queryDataMapTable(String datasystemid, String schema, String table) {
      TCoreDatamap dataMap = this.queryDataMapUnique(datasystemid, schema);
      if (dataMap == null) {
         return null;
      } else {
         TCoreDatamapTable dataMapTable = this.tCoreDatamapTableDao.queryDataMapTable(dataMap.getId(), table);
         return dataMapTable;
      }
   }

   public TCoreDatamapTable queryDataMapTableById(String tableid) {
      TCoreDatamapTable table = (TCoreDatamapTable)this.tCoreDatamapTableDao.get(tableid);
      return table;
   }

   public List<TCoreDatamapColumn> queryDataMapColumnById(String tablerelationid) {
      List<TCoreDatamapColumn> list = this.tCoreDatamapColumnDao.queryAll(new Criterion[]{Restrictions.eq("datamaptableid", tablerelationid)});
      return list;
   }

   public List<TCoreDatamapTable> queryDataMapTable(String datamapid, String excludetable) {
      List<TCoreDatamapTable> list = this.tCoreDatamapTableDao.queryAll(new Criterion[]{Restrictions.eq("datamapid", datamapid), Restrictions.ne("tablename", excludetable)});
      return list;
   }

   public TCoreDatamapTablerelation queryTableRelation(String datamapid, String sourcetableid, String targettableid) {
      TCoreDatamapTablerelation relation = this.tCoreDatamapTablerelationDao.queryTableRelation(datamapid, sourcetableid, targettableid);
      if (relation != null) {
         return relation;
      } else {
         relation = this.tCoreDatamapTablerelationDao.queryTableRelation(datamapid, targettableid, sourcetableid);
         return relation;
      }
   }

   public void saveDataMapTableRelation(String datamapid, String sourcetableid, String targettableid) {
      this.tCoreDatamapTablerelationDao.save(new TCoreDatamapTablerelation(sourcetableid, targettableid, "1", datamapid));
   }

   public void saveDataMapUserMap(TCoreDatamapUsermap usermap) {
      TCoreDatamapUsermap temp = this.tCoreDatamapUsermapDao.queryUnique(usermap.getUserid(), usermap.getTableid());
      if (temp == null) {
         this.tCoreDatamapUsermapDao.save(usermap);
      }
   }

   public List<TreeVO> initTree(String flag, String code, String text, String parentid, String alias, String userid) {
      List<TreeVO> tree_datasystem = new ArrayList();
      if (code != null && code.equals(EdataSystemGrade.DATASYSTEM.getCode())) {
         for(TCoreDatasystem item : this.tCoreDatasystemDao.queryAll(new Criterion[]{Restrictions.eq("flag", flag)})) {
            tree_datasystem.add(new TreeVO(item.getId(), item.getSysname(), "closed", TreeVO.CHECKED_FALSE, EdataSystemGrade.DATASYSTEM.getCode(), "icon-db", (List)null));
         }

         return tree_datasystem;
      } else if (code != null && code.equals(EdataSystemGrade.SCHEMA.getCode())) {
         Connection conn = this.getConnectionByDataSystemId(parentid);
         List<String> schemalist = JdbcTool.getDbSchemas(conn);
         JdbcTool.closeConnection(conn);

         for(String item : schemalist) {
            tree_datasystem.add(new TreeVO(parentid + item, item, "closed", TreeVO.CHECKED_FALSE, EdataSystemGrade.SCHEMA.getCode(), "icon-folder", (List)null));
         }

         return tree_datasystem;
      } else if (code != null && code.equals(EdataSystemGrade.TABLE.getCode())) {
         String datasystemid = parentid.replace(text, "");
         Connection conn = this.getConnectionByDataSystemId(datasystemid);
         List<String> tablelist = JdbcTool.getAllTableName(conn, text);
         JdbcTool.closeConnection(conn);
         TCoreDatamap dataMap = this.queryDataMapUnique(datasystemid, text);
         List<String> tableNameList = null;
         if (dataMap != null) {
            tableNameList = this.dataMapDao.queryUserMapTableName(dataMap.getId(), userid);
         }

         for(String item : tablelist) {
            TreeVO tabletree = new TreeVO(parentid + item, item, "open", TreeVO.CHECKED_FALSE, EdataSystemGrade.TABLE.getCode(), "icon-table", (List)null);
            tabletree.setNodename(item);
            if ("1".equals(alias)) {
               TCoreDatamapTablealias tableAlias = this.tCoreDatamapTablealiasDao.queryDataMapTableAlias(datasystemid, text, item);
               if (tableAlias != null && !"".equals(tableAlias.getTablebyname().trim())) {
                  tabletree.setNodebyname(tableAlias.getTablebyname().trim());
               }

               if (tableNameList != null && tableNameList.size() > 0 && tableNameList.contains(item)) {
                  tabletree.setIconCls("icon-user-table");
               }
            }

            tree_datasystem.add(tabletree);
         }

         return tree_datasystem;
      } else {
         return null;
      }
   }

   public List<TreeVO> initUserTree(String flag, String code, String text, String parentid, String alias, String userid) {
      List<TreeVO> tree_datasystem = new ArrayList();
      if (code != null && code.equals(EdataSystemGrade.DATASYSTEM.getCode())) {
         List<String> dataSystemIdList = this.dataMapDao.queryUserMapDataSystemId(userid);

         for(TCoreDatasystem item : this.tCoreDatasystemDao.queryAll(new Criterion[]{Restrictions.in("id", dataSystemIdList)})) {
            tree_datasystem.add(new TreeVO(item.getId(), item.getSysname(), "closed", TreeVO.CHECKED_FALSE, EdataSystemGrade.DATASYSTEM.getCode(), "icon-db", (List)null));
         }

         return tree_datasystem;
      } else if (code != null && code.equals(EdataSystemGrade.SCHEMA.getCode())) {
         List<String> schemaList = this.dataMapDao.queryUserMapSchema(userid, parentid);
         Connection conn = this.getConnectionByDataSystemId(parentid);
         List<String> schemalist = JdbcTool.getDbSchemas(conn);
         JdbcTool.closeConnection(conn);

         for(String item : schemalist) {
            if (schemaList != null && schemaList.size() > 0 && schemaList.contains(item)) {
               tree_datasystem.add(new TreeVO(parentid + item, item, "closed", TreeVO.CHECKED_FALSE, EdataSystemGrade.SCHEMA.getCode(), "icon-folder", (List)null));
            }
         }

         return tree_datasystem;
      } else if (code != null && code.equals(EdataSystemGrade.TABLE.getCode())) {
         String datasystemid = parentid.replace(text, "");
         Connection conn = this.getConnectionByDataSystemId(datasystemid);
         List<String> tablelist = JdbcTool.getAllTableName(conn, text);
         JdbcTool.closeConnection(conn);
         TCoreDatamap dataMap = this.queryDataMapUnique(datasystemid, text);
         List<String> tableNameList = null;
         if (dataMap != null) {
            tableNameList = this.dataMapDao.queryUserMapTableName(dataMap.getId(), userid);
         }

         for(String item : tablelist) {
            TreeVO tabletree = new TreeVO(parentid + item, item, "open", TreeVO.CHECKED_FALSE, EdataSystemGrade.TABLE.getCode(), "icon-table", (List)null);
            tabletree.setNodename(item);
            if ("1".equals(alias)) {
               TCoreDatamapTablealias tableAlias = this.tCoreDatamapTablealiasDao.queryDataMapTableAlias(datasystemid, text, item);
               if (tableAlias != null && !"".equals(tableAlias.getTablebyname().trim())) {
                  tabletree.setNodebyname(tableAlias.getTablebyname().trim());
               }

               if (tableNameList != null && tableNameList.size() > 0 && tableNameList.contains(item)) {
                  tabletree.setIconCls("icon-user-table");
                  tree_datasystem.add(tabletree);
               }
            }
         }

         return tree_datasystem;
      } else {
         return null;
      }
   }

   public List<TCoreDatamapTable> queryDataMapUserTable(String datamapid, String userid) {
      List<String> tableIdList = this.dataMapDao.queryTableId(datamapid, userid);
      List<TCoreDatamapTable> list = this.tCoreDatamapTableDao.queryAll(new Criterion[]{Restrictions.in("id", tableIdList)});
      return list;
   }

   public List<TCoreDatamapTable> queryDataMapUserTable(String datamapid, String userid, String excludetable) {
      List<String> tableIdList = this.dataMapDao.queryTableId(datamapid, userid);
      List<TCoreDatamapTable> list = this.tCoreDatamapTableDao.queryAll(new Criterion[]{Restrictions.in("id", tableIdList), Restrictions.ne("tablename", excludetable)});
      return list;
   }

   public void removeUserMap(String datamapid, String tableid, String userid) {
      this.tCoreDatamapUsermapDao.remove(new Criterion[]{Restrictions.eq("datamapid", datamapid), Restrictions.eq("tableid", tableid), Restrictions.eq("userid", userid)});
   }

   public void saveTableNote(TCoreDatamapTable table) {
      String note = table.getNote();
      table = (TCoreDatamapTable)this.tCoreDatamapTableDao.get(table.getId());
      table.setNote(note);
      this.tCoreDatamapTableDao.save(table);
   }

   public void saveColumnNote(TCoreDatamapColumn column) {
      String note = column.getNote();
      column = (TCoreDatamapColumn)this.tCoreDatamapColumnDao.get(column.getId());
      column.setNote(note);
      this.tCoreDatamapColumnDao.save(column);
   }

   public TCoreDatamap queryDataMap(String datamapid) {
      return (TCoreDatamap)this.tCoreDatamapDao.get(datamapid);
   }

   public TCoreMaskingTask queryMaskingTask(String engineid, String taskname) {
      TCoreMaskingTask task = (TCoreMaskingTask)this.tCoreMaskingTaskDao.queryUnique(new Criterion[]{Restrictions.eq("engineid", engineid), Restrictions.eq("taskname", taskname)});
      return task;
   }

   public TCoreMaskingTask saveTask(String userid, String engineid, String folderName, String taskname, String note, String tableid, String datatargetid, String datatargetschema, String targetTableName) {
      TCoreDatamapTable maptable = (TCoreDatamapTable)this.tCoreDatamapTableDao.get(tableid);
      TCoreDatamap datamap = (TCoreDatamap)this.tCoreDatamapDao.get(maptable.getDatamapid());
      TCoreDatasystem datasystem = (TCoreDatasystem)this.tCoreDatasystemDao.get(datamap.getDatasystemid());
      Connection sourceConnection = this.getConnectionByDataSystemId(datamap.getDatasystemid());
      Connection targetConnection = this.getConnectionByDataSystemId(datatargetid);
      JdbcTool.copyTable(sourceConnection, datamap.getDbschema(), maptable.getTablename(), targetConnection, datatargetschema, targetTableName);
      JdbcTool.closeConnection(sourceConnection);
      JdbcTool.closeConnection(targetConnection);
      TCoreMaskingTask task = new TCoreMaskingTask(taskname, new Date(), userid, engineid, folderName, (String)null, (String)null, (String)null, (String)null, (String)null, (String)null, (String)null, (String)null, (String)null);
      task.setNote(note);
      task.setFlag(EmaskingTaskType.DB_TO_DB.getFlag());
      this.tCoreMaskingTaskDao.save(task);
      String tablemappingkey = StringTool.getTablePrimaryKey();
      TCoreMaskingTable sourcetable = new TCoreMaskingTable(task.getId(), datasystem.getId(), datamap.getDbschema(), maptable.getTablename(), tablemappingkey, EmaskingDirection.DATA_SOURCE.getFlag());
      TCoreMaskingTable targettable = new TCoreMaskingTable(task.getId(), datatargetid, datatargetschema, targetTableName, tablemappingkey, EmaskingDirection.DATA_TARGET.getFlag());
      this.tCoreMaskingTableDao.save(sourcetable);
      this.tCoreMaskingTableDao.save(targettable);
      Connection conn = this.getConnectionByDataSystemId(datasystem.getId());

      for(ColumnInfo column : JdbcTool.getAllColumnInfo(conn, datamap.getDbschema(), maptable.getTablename())) {
         String columnmappingkey = StringTool.getTablePrimaryKey();
         TCoreMaskingTablecolumn sourcecolumn = new TCoreMaskingTablecolumn(task.getId(), sourcetable.getId(), columnmappingkey, EmaskingDirection.DATA_SOURCE.getFlag(), column.getColumnname(), (String)null, column.getColumnsize(), column.getColumnsize(), column.getDecimaldigits(), (String)null, column.getIsnullable(), 0, "", "", "");
         TCoreMaskingTablecolumn targetcolumn = new TCoreMaskingTablecolumn(task.getId(), targettable.getId(), columnmappingkey, EmaskingDirection.DATA_TARGET.getFlag(), column.getColumnname(), (String)null, column.getColumnsize(), column.getColumnsize(), column.getDecimaldigits(), (String)null, column.getIsnullable(), 0, "", "", "");
         this.tCoreMaskingTablecolumnDao.save(sourcecolumn);
         this.tCoreMaskingTablecolumnDao.save(targetcolumn);
      }

      JdbcTool.closeConnection(conn);
      return task;
   }
}
