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

import com.chenyang.nse.bussiness.config.PropertiesLoaderUtils;
import com.chenyang.nse.bussiness.dao.PageInfo;
import com.chenyang.nse.bussiness.dao.core.EngineDao;
import com.chenyang.nse.bussiness.dao.table.core.ImportMaskingExecuteDao;
import com.chenyang.nse.bussiness.dao.table.core.desensitizationtask.DesensitizationMonitorDao;
import com.chenyang.nse.bussiness.engine.infa.InfoProperty;
import com.chenyang.nse.bussiness.engine.infa.basic.webservice.LoginWebService;
import com.chenyang.nse.bussiness.engine.infa.basic.webservice.LogoutWebService;
import com.chenyang.nse.bussiness.engine.infa.basic.webservice.MultiGetSessionStatisticsWebService;
import com.chenyang.nse.bussiness.engine.infa.basic.webservice.SessionBean;
import com.chenyang.nse.bussiness.engine.infa.basic.wsclient.DIServiceInfo;
import com.chenyang.nse.bussiness.engine.infa.basic.wsclient.DataIntegrationInterface;
import com.chenyang.nse.bussiness.engine.infa.basic.wsclient.DataIntegrationService;
import com.chenyang.nse.bussiness.engine.infa.basic.wsclient.ETaskRunMode;
import com.chenyang.nse.bussiness.engine.infa.basic.wsclient.SessionHeader;
import com.chenyang.nse.bussiness.engine.infa.basic.wsclient.TypeStartWorkflowExRequest;
import com.chenyang.nse.bussiness.engine.infa.basic.wsclient.TypeStartWorkflowExResponse;
import com.chenyang.nse.bussiness.engine.infa.basic.wsclient.WorkflowRequest;
import com.chenyang.nse.bussiness.engine.infa.powercenter961.pubbean.ModifyImportFile;
import com.chenyang.nse.bussiness.engine.infa.powercenter961.pubtool.InfoExecUtil;
import com.chenyang.nse.bussiness.entity.orm.table.core.ImportMaskingExecute;
import com.chenyang.nse.bussiness.entity.vo.ResultVO;
import com.chenyang.nse.bussiness.service.core.ImportDesensitizationtaskService;
import com.chenyang.nse.bussiness.thread.ExecuteParam;
import com.chenyang.nse.bussiness.tools.jdbc.JdbcTool;
import com.chenyang.nse.bussiness.tools.object.ObjectTool;
import com.power.xml.utility.IgnoreDTDEntityResolver;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

@Service
@Transactional
public class ImportDesensitizationtaskServiceImpl implements ImportDesensitizationtaskService {
   private static Properties props = new Properties();
   @Autowired
   private EngineDao engineDao;
   @Autowired
   private ImportMaskingExecuteDao importMaskingExecuteDao;
   @Autowired
   private DesensitizationMonitorDao desensitizationMonitorDao;
   @Autowired
   private ThreadPoolTaskExecutor taskExecutor;

   public List<ImportMaskingExecute> queryTask(String taskname, PageInfo pageInfo) {
      List<ImportMaskingExecute> list = this.importMaskingExecuteDao.queryByPageInfo(pageInfo, Order.desc("importtime"), new Criterion[]{Restrictions.like("taskname", "%" + taskname + "%")});
      return list;
   }

   public ResultVO importTask(MultipartFile importfile) {
      ResultVO result = new ResultVO();
      result.setResult(false);
      result.setMessage("导入失败");
      String xml_file_path = File.separator + "data" + File.separator + "infa_work_report" + File.separator + "masking_task" + File.separator + importfile.getOriginalFilename();
      File desFile = new File(xml_file_path);
      if (!desFile.getParentFile().exists()) {
         desFile.mkdirs();
      }

      try {
         importfile.transferTo(desFile);
         InputStream inputStream = new FileInputStream(desFile);
         SAXReader reader = new SAXReader();
         reader.setEntityResolver(new IgnoreDTDEntityResolver());
         Document doc = reader.read(inputStream);
         List<Node> elementlist = doc.selectNodes("POWERMART/REPOSITORY/FOLDER/WORKFLOW");
         Date date = new Date();
         Map<String, Object> map = this.engineDao.queryEnginePropertyKeyValue(props.getProperty("engineid"));
         InfoProperty infoProperty = (InfoProperty)ObjectTool.getObjectByMap(InfoProperty.class, map);
         String con_file = ImportDesensitizationtaskServiceImpl.class.getResource("/").getPath().replaceAll("%20", " ") + "infofile" + File.separator + "con_import.xml";
         Element element = (Element)doc.selectSingleNode("POWERMART/REPOSITORY/FOLDER");
         Attribute isSelfAttr = element.attribute("NAME");
         String foldername = isSelfAttr.getText();
         String repository = infoProperty.getRepository();
         this.updateImportFile(con_file, foldername, repository);

         for(int i = 0; i < elementlist.size(); ++i) {
            Element workflowElement = (Element)elementlist.get(i);
            Attribute workflowAttr = workflowElement.attribute("NAME");
            String workflowName = workflowAttr.getText();
            ImportMaskingExecute importMaskingExecute = new ImportMaskingExecute();
            String id = UUID.randomUUID().toString();
            importMaskingExecute.setId(id);
            importMaskingExecute.setTaskname(workflowName);
            importMaskingExecute.setStatus(0);
            importMaskingExecute.setImporttime(date);
            importMaskingExecute.setFoldername(foldername);
            this.importMaskingExecuteDao.save(importMaskingExecute);

            try {
               System.out.println("开始导入任务名:" + workflowName + "的xml");
               String importlog = InfoExecUtil.executImport(infoProperty.getPmrepexepath(), xml_file_path, con_file, infoProperty.getXmldir() + File.separator + "log.txt");
               if (!importlog.contains("已成功完成") && !importlog.contains("successfully")) {
                  importMaskingExecute.setStatus(1);
                  this.importMaskingExecuteDao.saveOrUpdate(importMaskingExecute);
               } else {
                  result.setResult(true);
                  result.setMessage("导入成功");
                  importMaskingExecute.setStatus(2);
                  this.importMaskingExecuteDao.saveOrUpdate(importMaskingExecute);
               }
            } catch (Exception e) {
               importMaskingExecute.setStatus(1);
               this.importMaskingExecuteDao.saveOrUpdate(importMaskingExecute);
               e.printStackTrace();
            }
         }
      } catch (Exception e) {
         e.printStackTrace();
      }

      return result;
   }

   public ImportMaskingExecute getImportMaskingExecute(String taskid) {
      return (ImportMaskingExecute)this.importMaskingExecuteDao.get(taskid);
   }

   public void saveImportMaskingExecute(ImportMaskingExecute importMaskingExecute) {
      this.importMaskingExecuteDao.saveOrUpdate(importMaskingExecute);
   }

   public long getExeTaskNum() {
      return this.importMaskingExecuteDao.getExeTaskNum();
   }

   @Async
   public void executeTasks(final String taskid, List<Element> elementlist, String[] tids, final ExecuteParam executeParam, final Document doc) {
      try {
         final CountDownLatch countDownLatch = new CountDownLatch(elementlist.size());

         for(int i = 0; i < elementlist.size(); ++i) {
            final Element element = (Element)elementlist.get(i);
            final String id = tids[i];
            this.taskExecutor.execute(new Runnable() {
               public void run() {
                  try {
                     String status = "4";
                     String sessionId = LoginWebService.returnStatus(executeParam.getInfoProperty());
                     Attribute isSelfAttr = element.attribute("NAME");
                     String workflowName = isSelfAttr.getText();
                     ImportDesensitizationtaskServiceImpl.this.updateImportTask(workflowName, taskid);
                     int runId = ImportDesensitizationtaskServiceImpl.this.startWorkFlowEx(workflowName, executeParam.getInfoProperty(), executeParam.getFolderName(), sessionId);
                     String completeStatus = "0";
                     System.out.println("》》》》》》》》》》》》》》》runId=" + runId);
                     if (runId >= 0) {
                        completeStatus = ImportDesensitizationtaskServiceImpl.this.workflowTaskCompleteMonitor(executeParam.getInfoProperty(), executeParam.getFolderName(), workflowName, sessionId);
                     }

                     if ("1".equals(completeStatus)) {
                        System.out.println("表" + workflowName + ",执行完成,通过阻塞方法！");
                        Element taskelement = (Element)doc.selectSingleNode("POWERMART/REPOSITORY/FOLDER/WORKFLOW[@NAME='" + workflowName + "']/SESSION");
                        Attribute taskAttr = taskelement.attribute("NAME");
                        String mname = taskAttr.getText();
                        SessionBean sessionBean = ImportDesensitizationtaskServiceImpl.this.getLogForTaskMapping(executeParam.getFolderName(), executeParam.getInfoProperty(), workflowName, mname, sessionId);
                        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>status=" + sessionBean.getStatus());
                        if ("SUCCEEDED".equals(sessionBean.getStatus())) {
                           status = "1";
                        } else if ("FAILED".equals(sessionBean.getStatus())) {
                           status = "2";
                        } else if ("STOPPED".equals(sessionBean.getStatus())) {
                           status = "3";
                        } else {
                           status = "4";
                        }

                        System.out.println("执行更新监控表开始！tableName=" + workflowName);
                        ImportDesensitizationtaskServiceImpl.this.updateMonitor(workflowName, executeParam.getTableMap(), status, runId, id);
                     }

                     LogoutWebService.returnStatus(sessionId, executeParam.getInfoProperty());
                  } catch (Exception e) {
                     e.printStackTrace();
                  } finally {
                     countDownLatch.countDown();
                  }

               }
            });
         }
      } catch (Exception e) {
         e.printStackTrace();
      }

   }

   public void executeTask(final String taskid, final String id, final ExecuteParam executeParam, final String taskname) {
      try {
         final CountDownLatch countDownLatch = new CountDownLatch(1);
         this.taskExecutor.execute(new Runnable() {
            public void run() {
               try {
                  String status = "4";
                  String sessionId = LoginWebService.returnStatus(executeParam.getInfoProperty());
                  String workflowName = taskname;
                  ImportDesensitizationtaskServiceImpl.this.updateImportTask(workflowName, taskid);
                  int runId = ImportDesensitizationtaskServiceImpl.this.startWorkFlowEx(workflowName, executeParam.getInfoProperty(), executeParam.getFolderName(), sessionId);
                  String completeStatus = "0";
                  System.out.println("》》》》》》》》》》》》》》》runId=" + runId);
                  if (runId >= 0) {
                     completeStatus = ImportDesensitizationtaskServiceImpl.this.workflowTaskCompleteMonitor(executeParam.getInfoProperty(), executeParam.getFolderName(), workflowName, sessionId);
                  }

                  if ("1".equals(completeStatus)) {
                     System.out.println("表" + workflowName + ",执行完成,通过阻塞方法！");
                     SessionBean sessionBean = ImportDesensitizationtaskServiceImpl.this.getLogForTaskMapping(executeParam.getFolderName(), executeParam.getInfoProperty(), workflowName, taskname, sessionId);
                     System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>status=" + sessionBean.getStatus());
                     if ("SUCCEEDED".equals(sessionBean.getStatus())) {
                        status = "1";
                     } else if ("FAILED".equals(sessionBean.getStatus())) {
                        status = "2";
                     } else if ("STOPPED".equals(sessionBean.getStatus())) {
                        status = "3";
                     } else {
                        status = "4";
                     }

                     System.out.println("执行更新监控表开始！tableName=" + workflowName);
                     ImportDesensitizationtaskServiceImpl.this.updateMonitor(workflowName, executeParam.getTableMap(), status, runId, id);
                  }

                  LogoutWebService.returnStatus(sessionId, executeParam.getInfoProperty());
               } catch (Exception e) {
                  e.printStackTrace();
               } finally {
                  countDownLatch.countDown();
               }

            }
         });
      } catch (Exception e) {
         e.printStackTrace();
      }

   }

   public void updateImportFile(String filepath, String foldername, String repository) throws Exception {
      File file = new File(filepath);
      ModifyImportFile mi = new ModifyImportFile();
      ModifyImportFile.updateConfigFileXML("TARGETFOLDERNAME", file, foldername);
      ModifyImportFile.updateConfigFileXML("SOURCEFOLDERNAME", file, foldername);
      ModifyImportFile.updateConfigFileXML("TARGETREPOSITORYNAME", file, repository);
      ModifyImportFile.updateConfigFileXML("SOURCEREPOSITORYNAME", file, repository);
   }

   public int startWorkFlowEx(String workflowName, InfoProperty engine, String folderName, String sessionId) {
      int runId = -1;
      DataIntegrationInterface webService = (new DataIntegrationService()).getDataIntegration();
      DIServiceInfo dIServiceInfo = new DIServiceInfo();
      dIServiceInfo.setDomainName(engine.getDomainname());
      dIServiceInfo.setServiceName(engine.getInteservicename());
      TypeStartWorkflowExRequest typeStartWorkflowExRequest = new TypeStartWorkflowExRequest();
      typeStartWorkflowExRequest.setDIServiceInfo(dIServiceInfo);
      typeStartWorkflowExRequest.setFolderName(folderName);
      typeStartWorkflowExRequest.setWorkflowName(workflowName);
      typeStartWorkflowExRequest.setRequestMode(ETaskRunMode.RECOVERY);

      try {
         SessionHeader sessionHeader = new SessionHeader();
         sessionHeader.setSessionId(sessionId);
         TypeStartWorkflowExResponse startWorkflowEx = webService.startWorkflowEx(typeStartWorkflowExRequest, sessionHeader);
         runId = startWorkflowEx.getRunId();
      } catch (Exception e) {
         e.printStackTrace();
      }

      return runId;
   }

   public InfoProperty getInfoProperty() {
      Map<String, Object> map = this.engineDao.queryEnginePropertyKeyValue(props.getProperty("engineid"));
      InfoProperty engine = (InfoProperty)ObjectTool.getObjectByMap(InfoProperty.class, map);
      return engine;
   }

   public int saveDesensitizationMonitor(StringBuilder sql) {
      return this.desensitizationMonitorDao.saveDesensitizationMonitor(sql);
   }

   public void updateMonitor(String tableNane, Map<String, String> tableMap, String status, int runid, String id) {
      new Properties();

      try {
         Properties props = PropertiesLoaderUtils.loadAllProperties("config.properties");
         String sqlurl = props.get("jdbc.url").toString();
         String username = props.get("jdbc.user").toString();
         String password = props.get("jdbc.password").toString();
         String driver = props.get("jdbc.driver").toString();
         Connection connection = JdbcTool.getConnection(driver, sqlurl, username, password);
         Statement statement = connection.createStatement();
         String sql = "UPDATE desensitization_monitor SET flag = '" + status + "',runid = '" + runid + "' WHERE id = '" + id + "'";
         System.out.println("update:desensitization_monitor=" + sql);
         statement.executeUpdate(sql.toString());
         statement.close();
         connection.close();
      } catch (IOException e) {
         e.printStackTrace();
      } catch (SQLException e) {
         e.printStackTrace();
      }

   }

   public void updateImportTask(String workFlowName, String taskId) {
      new Properties();

      try {
         Properties props = PropertiesLoaderUtils.loadAllProperties("config.properties");
         String sqlurl = props.get("jdbc.url").toString();
         String username = props.get("jdbc.user").toString();
         String password = props.get("jdbc.password").toString();
         String driver = props.get("jdbc.driver").toString();
         Connection connection = JdbcTool.getConnection(driver, sqlurl, username, password);
         Statement statement = connection.createStatement();
         String sql = "UPDATE import_masking_execute SET taskname = '" + workFlowName + "' WHERE id = '" + taskId + "'";
         System.out.println("update:import_masking_execute=" + sql);
         statement.executeUpdate(sql.toString());
         statement.close();
         connection.close();
      } catch (IOException e) {
         e.printStackTrace();
      } catch (SQLException e) {
         e.printStackTrace();
      }

   }

   public String workflowTaskCompleteMonitor(InfoProperty engine, String folderName, String workflowName, String sessionId) {
      String completeStatus = "0";
      DataIntegrationInterface webService = (new DataIntegrationService()).getDataIntegration();
      DIServiceInfo dIServiceInfo = new DIServiceInfo();
      dIServiceInfo.setDomainName(engine.getDomainname());
      dIServiceInfo.setServiceName(engine.getInteservicename());
      WorkflowRequest workflowRequest = new WorkflowRequest();
      workflowRequest.setDIServiceInfo(dIServiceInfo);
      workflowRequest.setFolderName(folderName);
      workflowRequest.setWorkflowName(workflowName);

      try {
         SessionHeader sessionHeader = new SessionHeader();
         sessionHeader.setSessionId(sessionId);
         webService.waitTillWorkflowComplete(workflowRequest, sessionHeader);
      } catch (Exception var10) {
         System.out.println("该工作流未运行，或者已完成！");
      }

      completeStatus = "1";
      return completeStatus;
   }

   public SessionBean getLogForTaskMapping(String folerName, InfoProperty engine, String name, String mname, String sessionId) {
      SessionBean se = new SessionBean();

      try {
         se = MultiGetSessionStatisticsWebService.returnStatus1(sessionId, engine, name, mname, folerName);
      } catch (Exception e) {
         se.setStatus("EXCEPTION");
         e.printStackTrace();
      }

      return se;
   }

   public List<ImportMaskingExecute> queryTaskList(String taskid) {
      List<ImportMaskingExecute> list = this.importMaskingExecuteDao.queryAll(new Criterion[]{Restrictions.eq("id", taskid)});
      return list;
   }

   public void removetask(String taskid) {
      this.importMaskingExecuteDao.remove(new Criterion[]{Restrictions.eq("id", taskid)});
   }

   static {
      try {
         props = PropertiesLoaderUtils.loadAllProperties("config.properties");
      } catch (IOException e) {
         e.printStackTrace();
      }

   }
}
