package com.chenyang.nse.bussiness.controller.api;

import com.chenyang.nse.bussiness.engine.infa.InfoProperty;
import com.chenyang.nse.bussiness.entity.orm.table.core.TCoreDatasystem;
import com.chenyang.nse.bussiness.entity.orm.table.core.desensitizationtask.DesensitizationMonitor;
import com.chenyang.nse.bussiness.entity.orm.table.core.desensitizationtask.DesensitizationTable;
import com.chenyang.nse.bussiness.entity.orm.table.core.desensitizationtask.Desensitizationsource;
import com.chenyang.nse.bussiness.entity.orm.table.core.desensitizationtask.Desensitizationtarget;
import com.chenyang.nse.bussiness.entity.orm.table.core.desensitizationtask.Desensitizationtask;
import com.chenyang.nse.bussiness.service.core.DataSystemService;
import com.chenyang.nse.bussiness.service.core.DesensitizationtaskService;
import com.chenyang.nse.bussiness.service.redis.RedisService;
import com.chenyang.nse.bussiness.thread.ExecuteParam;
import com.chenyang.nse.bussiness.tools.jdbc.JdbcTool;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping({"/api"})
public class API {
   public static final String DB_pwc_FILE_batchwrite_DB = "DBtoDB,normal,batchwrite";
   public static final String DB_batchread_FILE_pwc_DB = "DBtoDB,batchread,normal";
   public static final String DB_batchread_FILE_pwc_FILE_batchwrite_DB = "DBtoDB,batchread,batchwrite";
   public static final String DB_pwc_DB = "DBtoDB,normal,normal";
   public static final String DB_pwc_FILE = "DBtoFILE,normal";
   public static final String DB_batchread_FILE_pwc_FILE = "DBtoFILE,batchread";
   public static final String FILE_pwc_FILE_batchwrite_DB = "FILEtoDB,batchwrite";
   public static final String FILE_pwc_DB = "FILEtoDB,normal";
   public static final String FILE_pwc_FILE = "FILEtoFILE";
   public static final String HIVE_batchread_FILE_pwc_FILE_batchwrite_HIVE = "HIVEtoHIVE,batchread,batchwrite";
   @Autowired
   private DesensitizationtaskService desensitizationtaskService;
   @Autowired
   private DataSystemService dataSystemService;
   @Autowired
   private RedisService redisService;
   private static final Logger logger = LoggerFactory.getLogger(API.class);

   @RequestMapping({"/executetask"})
   public void executeTask(HttpServletRequest request, HttpServletResponse response, String taskname) throws UnsupportedEncodingException {
      System.out.println("==============通过任务名启动任务开始！==============");
      System.out.println("--------------taskname=" + taskname + "--------------");
      String encoding = getEncoding(taskname);
      System.out.println("--------------encoding=" + encoding + "--------------");

      try {
         Map<String, Object> map = this.parse(request);
         System.out.println("------------map=" + map);
         Map<String, Object> mapParameter = (Map)map.get("parameter");
         taskname = (String)mapParameter.get("taskname");
         System.out.println("==============parameter taskname=" + taskname + "===============");
         Desensitizationtask desensitizationtask = this.desensitizationtaskService.queryTaskByName(taskname, "");
         PrintWriter writer = response.getWriter();
         if (desensitizationtask == null) {
            writer.print("Get the task exception, make sure the task name is correct!");
            writer.flush();
            writer.close();
            return;
         }

         System.out.println("获取任务成功，即将开始执行脱敏!");
         String taskid = desensitizationtask.getId();
         Desensitizationsource desensitizationsource = this.desensitizationtaskService.querySourceInfo(taskid);
         Desensitizationtarget desensitizationtarget = this.desensitizationtaskService.queryTargetById(taskid);
         TCoreDatasystem tCoreDatasystemSource = new TCoreDatasystem();
         TCoreDatasystem tCoreDatasystemTarget = new TCoreDatasystem();
         if (desensitizationsource.getDatasourceid() != null && !"".equals(desensitizationsource.getDatasourceid())) {
            tCoreDatasystemSource = this.dataSystemService.queryDataSystemById(desensitizationsource.getDatasourceid());
         } else {
            tCoreDatasystemSource.setDbtype("FILE");
         }

         if (desensitizationtarget.getDatasourceid() != null && !"".equals(desensitizationtarget.getDatasourceid())) {
            tCoreDatasystemTarget = this.dataSystemService.queryDataSystemById(desensitizationtarget.getDatasourceid());
         } else {
            tCoreDatasystemTarget.setDbtype("FILE");
         }

         String type = JdbcTool.returnType(desensitizationsource.getExecution_type(), desensitizationtarget.getExecution_type(), desensitizationtask.getTasktype());
         InfoProperty infoProperty = this.desensitizationtaskService.getInfoProperty();
         long groupId = (new Date()).getTime();
         ExecuteParam executeParam = new ExecuteParam();
         executeParam.setSourceDataSystem(tCoreDatasystemSource);
         executeParam.setTargetDataSystem(tCoreDatasystemTarget);
         executeParam.setInfoProperty(infoProperty);
         executeParam.setDataSourceId(desensitizationsource.getDatasourceid());
         executeParam.setDataTargetId(desensitizationtarget.getDatasourceid());
         executeParam.setFolderName(desensitizationtask.getFoldername());
         executeParam.setSourceSchemaName(desensitizationsource.getDataschema());
         executeParam.setTargetSchemaName(desensitizationtarget.getDataschema());
         executeParam.setIsPrimary(desensitizationtarget.getIsprimary());
         executeParam.setIsIndex(desensitizationtarget.getIsindex());
         executeParam.setTaskid(taskid);
         executeParam.setSourceFileDir(desensitizationsource.getSourcefiledir());
         executeParam.setTaskNameReal(desensitizationtask.getTasknamereal());
         executeParam.setSourcetype(desensitizationsource.getExecution_type());
         executeParam.setTargettype(desensitizationtarget.getExecution_type());
         executeParam.setLoadscripttype(desensitizationtarget.getLoadscripttype());
         String taskType = JdbcTool.returnTaskType(desensitizationtask.getTasktype());
         List<DesensitizationTable> tableList = this.desensitizationtaskService.queryTableList(taskid);
         Map<String, String> tableMap = new HashMap();
         StringBuilder batchInserSql = new StringBuilder();
         List<String> list_table = JdbcTool.sql_insert_q(new DesensitizationMonitor());
         list_table.add("id");
         String sqlBase = JdbcTool.sql_insert_z(list_table, "desensitization_monitor");
         batchInserSql.append(sqlBase);

         for(DesensitizationTable desensitizationTable : tableList) {
            String id = UUID.randomUUID().toString();
            tableMap.put(desensitizationTable.getTablename(), id);
            DesensitizationMonitor desensitizationMonitor = new DesensitizationMonitor();
            desensitizationMonitor.setId(id);
            desensitizationMonitor.setSourcename(desensitizationTable.getTablename());
            desensitizationMonitor.setTargetname(desensitizationTable.getTablename());
            desensitizationMonitor.setRunstatus(0);
            desensitizationMonitor.setGroupid(new BigInteger(String.valueOf(groupId)));
            desensitizationMonitor.setTaskid(taskid);
            desensitizationMonitor.setTasktype(taskType);
            batchInserSql.append(JdbcTool.sql_insert_h(desensitizationMonitor, list_table));
         }

         executeParam.setTableMap(tableMap);
         this.desensitizationtaskService.saveDesensitizationMonitor(batchInserSql.deleteCharAt(batchInserSql.length() - 1));
         switch (type) {
            case "DBtoDB,normal,batchwrite":
               this.desensitizationtaskService.executeDB_pwc_FILE_batchwrite_DB(executeParam);
               break;
            case "FILEtoDB,batchwrite":
               this.desensitizationtaskService.executeFILE_pwc_FILE_batchwrite_DB(executeParam);
               break;
            case "DBtoDB,batchread,batchwrite":
               this.desensitizationtaskService.executeDB_batchread_FILE_pwc_FILE_batchwrite_DB(executeParam);
               break;
            case "DBtoFILE,batchread":
               this.desensitizationtaskService.executeDB_batchread_FILE_pwc_FILE(executeParam);
               break;
            case "DBtoDB,batchread,normal":
               this.desensitizationtaskService.executeDB_batchread_FILE_pwc_DB(executeParam);
               break;
            default:
               if (desensitizationtask.getTasktype().contains("HIVE")) {
                  if ("oracledmp".equals(executeParam.getSourcetype())) {
                     this.desensitizationtaskService.executeDB_batchread_FILE_pwc_FILE_batchwrite_DB(executeParam);
                  } else {
                     this.desensitizationtaskService.executeTask(executeParam);
                  }
               } else {
                  this.desensitizationtaskService.executeTaskNormal(executeParam);
               }
         }

         writer.print("Desensitization has been successfully initiated!");
         writer.flush();
         writer.close();
      } catch (Exception e) {
         System.out.println("==============通过任务名启动任务异常！==============");
         e.printStackTrace();
      }

   }

   @RequestMapping({"/requestFor"})
   public void requestFor(HttpServletRequest request, HttpServletResponse response, String taskname) {
      Runtime rn = Runtime.getRuntime();
      System.out.println("taskname============================" + taskname);
      String encoding1 = getEncoding(taskname);
      System.out.println("encoding1----------------------------" + encoding1);

      try {
         String taskname2 = new String(taskname.getBytes(), "UTF-8");
         String encoding2 = getEncoding(taskname2);
         System.out.println("encoding2----------------------------" + encoding2);
         Properties initProp = new Properties(System.getProperties());
         System.out.println("当前系统编码:" + initProp.getProperty("file.encoding"));
         System.out.println("当前系统语言:" + initProp.getProperty("user.language"));
         Process process = rn.exec("/data/api/script/executetask.sh " + taskname2);
         process.waitFor();
      } catch (Exception e) {
         e.printStackTrace();
      }

   }

   @RequestMapping({"/test"})
   public void test(HttpServletRequest request, HttpServletResponse response, String keyLike) {
      logger.info("成功了。。。。");
   }

   protected Map<String, Object> parse(HttpServletRequest request) throws IOException {
      request.setCharacterEncoding("UTF-8");
      Map<String, Object> requestMap = new HashMap();
      Map<String, Object> headerMap = new HashMap();
      Enumeration<String> headerNames = request.getHeaderNames();

      while(headerNames != null && headerNames.hasMoreElements()) {
         String headerName = (String)headerNames.nextElement();
         headerMap.put(headerName, request.getHeader(headerName));
      }

      if (!headerMap.isEmpty()) {
         requestMap.put("header", headerMap);
      }

      Map<String, Object> parameterMap = new HashMap();
      Enumeration<String> parameterNames = request.getParameterNames();

      while(parameterNames != null && parameterNames.hasMoreElements()) {
         String parameterName = (String)parameterNames.nextElement();
         parameterMap.put(parameterName, request.getParameter(parameterName));
      }

      if (!parameterMap.isEmpty()) {
         requestMap.put("parameter", parameterMap);
      }

      Map<String, Object> attributeMap = new HashMap();
      Enumeration<String> requestAttributeNames = request.getAttributeNames();

      while(requestAttributeNames != null && requestAttributeNames.hasMoreElements()) {
         String attributeName = (String)requestAttributeNames.nextElement();
         if (!attributeName.startsWith("org.springframework")) {
            attributeMap.put(attributeName, request.getAttribute(attributeName));
         }
      }

      if (!attributeMap.isEmpty()) {
         requestMap.put("attribute", attributeMap);
      }

      requestMap.put("body", (new String(this.readBytes(request.getInputStream(), request.getContentLength()))).trim());
      return requestMap;
   }

   protected byte[] readBytes(InputStream is, int contentLen) {
      if (contentLen > 0) {
         int readLen = 0;
         int readLengthThisTime = 0;
         byte[] message = new byte[contentLen];

         try {
            while(readLen != contentLen) {
               readLengthThisTime = is.read(message, readLen, contentLen - readLen);
               if (readLengthThisTime == -1) {
                  break;
               }

               readLen += readLengthThisTime;
            }

            return message;
         } catch (IOException e) {
            e.printStackTrace();
         }
      }

      return new byte[0];
   }

   public static String getEncoding(String str) {
      String encode = "GB2312";

      try {
         if (str.equals(new String(str.getBytes(encode), encode))) {
            return encode;
         }
      } catch (Exception exception) {
         exception.printStackTrace();
      }

      encode = "ISO-8859-1";

      try {
         if (str.equals(new String(str.getBytes(encode), encode))) {
            return encode;
         }
      } catch (Exception exception1) {
         exception1.printStackTrace();
      }

      encode = "UTF-8";

      try {
         if (str.equals(new String(str.getBytes(encode), encode))) {
            return encode;
         }
      } catch (Exception exception2) {
         exception2.printStackTrace();
      }

      encode = "GBK";

      try {
         if (str.equals(new String(str.getBytes(encode), encode))) {
            return encode;
         }
      } catch (Exception exception3) {
         exception3.printStackTrace();
      }

      return null;
   }
}
