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

import com.chenyang.nse.bussiness.annot.PassToken;
import com.chenyang.nse.bussiness.annot.PullRegister;
import com.chenyang.nse.bussiness.commmon.json.ErrCode;
import com.chenyang.nse.bussiness.commmon.json.RespHelper;
import com.chenyang.nse.bussiness.commmon.json.Response;
import com.chenyang.nse.bussiness.dao.table.core.TCoreDatasystemDao;
import com.chenyang.nse.bussiness.dao.table.core.dataproject.TCoreDataProjectDao;
import com.chenyang.nse.bussiness.entity.orm.table.core.TCoreDatasystem;
import com.chenyang.nse.bussiness.entity.vo.encyption.TCoreClientIpControlledVo;
import com.chenyang.nse.bussiness.jar.db.ClientIpControlledReq;
import com.chenyang.nse.bussiness.jar.db.TCoreClientInfo;
import com.chenyang.nse.bussiness.jar.db.TCoreClientInfoDao;
import com.chenyang.nse.bussiness.jar.db.TCoreClientIpControlled;
import com.chenyang.nse.bussiness.jar.db.TCoreClientIpControlledDao;
import com.chenyang.nse.bussiness.jar.db.TCoreClientRuleChangeLog;
import com.chenyang.nse.bussiness.jar.db.TCoreClientRuleChangeLogDao;
import com.chenyang.nse.bussiness.jar.util.JarClientUtil;
import com.chenyang.nse.bussiness.service.console.UserService;
import com.chenyang.nse.bussiness.service.core.encryption.EncryptionProxyService;
import com.chenyang.nse.bussiness.tools.string.StringTool;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping({"jar_socket_controller"})
public class JarSocketController {
   @Autowired
   EncryptionProxyService proxyService;
   @Autowired
   private UserService userService;
   @Autowired
   private TCoreClientInfoDao clientInfoDao;
   @Autowired
   private TCoreClientRuleChangeLogDao ruleChangeLogDao;
   @Autowired
   private TCoreClientIpControlledDao clientIpControlledDao;
   @Autowired
   TCoreDataProjectDao tCoreDataProjectDao;
   @Autowired
   TCoreDatasystemDao tCoreDatasystemDao;
   static final long CLIENT_SYNC_TIMEOUT = 600000L;
   static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

   @PassToken
   @PullRegister
   @RequestMapping({"noticePullStatus"})
   public Response noticePullStatus(HttpServletRequest request, @RequestBody Map<String, String> map) {
      Map<String, String> params = JarClientUtil.getRequestParamsMap(request);
      String projectId = (String)params.get("projectId");
      String remoteHost = (String)params.get("remoteHost");
      String remotePort = (String)params.get("remotePort");
      String status = (String)params.get("status");
      TCoreClientInfo clientInfo = this.clientInfoDao.queryJarClients(remoteHost, Integer.parseInt(remotePort), projectId);
      clientInfo.setClient_status(status.charAt(0));
      if (null != map.get("databaseUrl")) {
         clientInfo.setDatabaseUrl(((String)map.get("databaseUrl")).toString());
      }

      if (null != map.get("clientError")) {
         clientInfo.setClientError((String)map.get("clientError"));
         clientInfo.setErrorTime(new Date());
      }

      this.clientInfoDao.saveOrUpdate(clientInfo);

      try {
         if ("2".equalsIgnoreCase(status)) {
            return RespHelper.successResp(JarClientUtil.isUpdateLastOptTime(remoteHost, Integer.parseInt(remotePort), projectId) ? "refresh" : "noRefresh");
         } else {
            return "3".equalsIgnoreCase(status) ? RespHelper.successResp("客户端已执行完全部拉取动作，本次同步完成！") : RespHelper.errResp(ErrCode.REQ_PARAM_ERROR);
         }
      } catch (Exception var10) {
         return RespHelper.errResp(ErrCode.SERVER_EXCEPTION);
      }
   }

   @PostMapping({"/pullAppUserOriginalInfos"})
   @ResponseBody
   @PassToken
   @PullRegister
   public Response<String> push2EncryptionProxy(@RequestBody Map<String, String> param, HttpServletRequest request) {
      Map<String, String> params = JarClientUtil.getRequestParamsMap(request);
      String projectId = (String)params.get("projectId");
      String remoteHost = (String)params.get("remoteHost");
      String remotePort = (String)params.get("remotePort");
      String status = (String)params.get("status");

      try {
         String appUserOriginal = this.proxyService.sendAppUserOriginalToTargetProxy(projectId, "pull");
         JarClientUtil.log("收到" + remoteHost + ":" + remotePort + "的拉取请求->应用用户是否明文，拉取内容为【" + appUserOriginal + "】");
         return RespHelper.<String>successResp(appUserOriginal);
      } catch (Exception e) {
         e.printStackTrace();
         return RespHelper.<String>errResp(ErrCode.SERVER_EXCEPTION);
      }
   }

   @PostMapping({"/pullGatewayOriginalInfos"})
   @ResponseBody
   @PassToken
   @PullRegister
   public Response<String> pushGatewayOriginalInfos(@RequestBody Map<String, String> param, HttpServletRequest request) {
      Map<String, String> params = JarClientUtil.getRequestParamsMap(request);
      String projectId = (String)params.get("projectId");
      String remoteHost = (String)params.get("remoteHost");
      String remotePort = (String)params.get("remotePort");
      String status = (String)params.get("status");
      String projectid = (String)param.get("projectid");

      try {
         String gatewayOriginal = this.proxyService.sendGatewatUserOriginalToTargetProxy(projectId, "pull");
         JarClientUtil.log("收到" + remoteHost + ":" + remotePort + "的拉取请求->网关平台用户“是否明文”，拉取内容为【" + gatewayOriginal + "】");
         return RespHelper.<String>successResp(gatewayOriginal);
      } catch (Exception e) {
         e.printStackTrace();
         JarClientUtil.log(remoteHost, Integer.parseInt(remotePort), "controller:拉取加密网关平台用户【是否启用明文】的配置信息报错");
         return RespHelper.<String>errResp(ErrCode.SERVER_EXCEPTION);
      }
   }

   @ResponseBody
   @RequestMapping({"/pullGlobalOriginalConfig"})
   @PassToken
   @PullRegister
   public Response<Integer> pushGlobalOriginalConfig(@RequestBody Map<String, Object> param, HttpServletRequest request) throws Exception {
      Map<String, String> params = JarClientUtil.getRequestParamsMap(request);
      String projectId = (String)params.get("projectId");
      String remoteHost = (String)params.get("remoteHost");
      String remotePort = (String)params.get("remotePort");
      String status = (String)params.get("status");

      try {
         Integer config = this.userService.pullGlobalOriginalConfig(projectId);
         JarClientUtil.log("收到" + remoteHost + ":" + remotePort + "的拉取请求->“是否启用插件”，拉取内容为【" + config + "】");
         return RespHelper.<Integer>successResp(config == null ? 0 : config);
      } catch (Exception e) {
         e.printStackTrace();
         JarClientUtil.log(remoteHost, Integer.parseInt(remotePort), "controller:拉取全局配置【是否启用明文】的配置信息报错");
         RespHelper.errResp(ErrCode.SERVER_EXCEPTION);
         return RespHelper.<Integer>successResp();
      }
   }

   @PostMapping({"list"})
   @PassToken
   public Response list(@RequestBody Map<String, Object> params) {
      String projectid = (String)params.get("projectid");
      Integer currentpage = (Integer)params.get("currentpage");
      Integer pageSize = (Integer)params.get("pageSize");
      String clientIp = (String)params.get("clientIp");
      String clientPortStr = (String)params.get("clientPort");
      int clientPort = clientPortStr == null ? 0 : (StringUtils.isNotEmpty(clientPortStr) ? Integer.parseInt(clientPortStr) : 0);
      String syncStatus = (String)params.get("syncStatus");
      String isForbidden = (String)params.get("isForbidden");

      try {
         List<TCoreClientInfo> list = this.clientInfoDao.list(projectid, currentpage, pageSize, clientIp, clientPort, syncStatus, isForbidden);
         if (list != null && list.size() > 0) {
            for(TCoreClientInfo clientInfo : list) {
               long lastReqTime = sdf.parse(clientInfo.getLast_req_time()).getTime();
               long now = (new Date()).getTime();
               if (now - lastReqTime > 600000L) {
                  clientInfo.setIsTimeout("1");
               } else {
                  clientInfo.setIsTimeout("0");
               }
            }

            for(TCoreClientInfo clientInfo : list) {
               if (null == clientInfo.getClientError() || "".equals(clientInfo.getClientError())) {
                  clientInfo.setErrorTime((Date)null);
               }

               if (JarClientUtil.checkAuth(projectid, clientInfo.getClient_ip())) {
                  clientInfo.setIsForbidden("0");
                  clientInfo.setIs_controlled('0');
               } else {
                  clientInfo.setIsForbidden("1");
                  clientInfo.setIs_controlled('1');
               }

               String status = "1";
               String url = clientInfo.getDatabaseUrl();
               if (null != url && !"".equals(url)) {
                  String dbType = this.getDbType(url);
                  if (null != url && !"".equals(dbType)) {
                     String ip = this.getIp(url);

                     try {
                        List<TCoreDatasystem> datasystemList = this.tCoreDatasystemDao.getbyprojectid(clientInfo.getProject_id());
                        status = "2";

                        for(int i = 0; i < datasystemList.size(); ++i) {
                           if (((TCoreDatasystem)datasystemList.get(i)).getDbip().equals(ip)) {
                              status = "1";
                              break;
                           }
                        }

                        clientInfo.setDatabaseUrlStatus(status);
                     } catch (Exception var19) {
                     }

                     String schema = this.getSchema(dbType, url);
                     if (schema.equals("")) {
                        status = "2";
                        clientInfo.setDatabaseUrlStatus(status);
                     }
                  } else {
                     status = "2";
                     clientInfo.setDatabaseUrlStatus(status);
                  }
               } else {
                  clientInfo.setDatabaseUrlStatus(status);
               }
            }
         }

         return RespHelper.successResp(list, this.clientInfoDao.getTotalPageForList(projectid, clientIp, clientPort, syncStatus, isForbidden));
      } catch (Exception var20) {
         return RespHelper.errResp(ErrCode.SERVER_EXCEPTION);
      }
   }

   @PostMapping({"changeLog"})
   @PassToken
   public Response changeLog(@RequestBody Map<String, Object> params) {
      try {
         String clientId = (String)params.get("clientId");
         Integer currentpage = (Integer)params.get("currentpage");
         Integer pageSize = (Integer)params.get("pageSize");
         List<TCoreClientRuleChangeLog> logs = this.ruleChangeLogDao.queryLogs(clientId, currentpage, pageSize);
         return RespHelper.successResp(logs, this.ruleChangeLogDao.queryLogsTotal(clientId));
      } catch (Exception var6) {
         return RespHelper.errResp(ErrCode.SERVER_EXCEPTION);
      }
   }

   @PostMapping({"delete"})
   @PassToken
   public Response deleteClient(@RequestBody Map<String, Object> params) {
      try {
         String clientId = (String)params.get("clientId");
         this.clientInfoDao.removeById(clientId);
         return RespHelper.successResp();
      } catch (Exception var3) {
         return RespHelper.errResp(ErrCode.SERVER_EXCEPTION);
      }
   }

   @PostMapping({"ipsList"})
   @PassToken
   public Response ipsList(@RequestBody Map<String, Object> params) {
      try {
         String projectId = (String)params.get("projectId");
         List<TCoreClientIpControlled> ips = this.clientIpControlledDao.list(projectId);
         List<TCoreClientIpControlledVo> ipvos = new ArrayList();

         for(TCoreClientIpControlled ip : ips) {
            TCoreClientIpControlledVo ipvo = new TCoreClientIpControlledVo();
            ipvo.setId(ip.getId());
            ipvo.setIsDelete(ip.getIs_delete());
            ipvo.setIs_delete(ip.getIs_delete());
            ipvo.setIsEquals(ip.getIs_equals());
            ipvo.setIs_equals(ip.getIs_equals());
            ipvo.setProjectid(ip.getProject_id());
            ipvo.setProject_id(ip.getProject_id());
            ipvo.setType(ip.getType());
            ipvo.setContent(ip.getContent());
            ipvos.add(ipvo);
         }

         return RespHelper.successResp(ipvos);
      } catch (Exception e) {
         e.printStackTrace();
         return RespHelper.errResp(ErrCode.SERVER_EXCEPTION);
      }
   }

   @PostMapping({"ipsSave"})
   @PassToken
   public Response ipsSave(@RequestBody ClientIpControlledReq req) {
      try {
         String projectId = req.getProjectId();
         this.clientIpControlledDao.remove(new Criterion[]{Restrictions.eq("project_id", projectId)});
         List<TCoreClientIpControlledVo> ips = req.getIps();
         if (ips.size() > 0) {
            for(TCoreClientIpControlledVo ipvo : ips) {
               TCoreClientIpControlled ip = new TCoreClientIpControlled();
               ip.setProject_id(projectId);
               ip.setIs_equals(ipvo.getIsEquals());
               ip.setType(ipvo.getType());
               ip.setContent(ipvo.getContent());
               ip.setId(StringTool.getTablePrimaryKey());
               this.clientIpControlledDao.save(ip);
            }
         }

         return RespHelper.successResp();
      } catch (Exception e) {
         e.printStackTrace();
         return RespHelper.errResp(ErrCode.SERVER_EXCEPTION);
      }
   }

   private String getDbType(String url) {
      String dbType = "";
      String getDatabaseType = "jdbc:masking:(mysql|oracle|kingbase|sqlserver|db2|dm|postgresql):.*?";
      Pattern pattern = Pattern.compile(getDatabaseType, 2);

      for(Matcher matcher = pattern.matcher(url); matcher.find(); dbType = matcher.group(1)) {
      }

      return dbType;
   }

   private String getIp(String url) {
      String ip = "";
      String getIp = "(\\d{1,3}\\.){3}\\d{1,3}";
      Pattern pattern = Pattern.compile(getIp);

      for(Matcher matcher = pattern.matcher(url); matcher.find(); ip = matcher.group(0)) {
      }

      return ip;
   }

   private String getSchema(String dbType, String url) {
      String schema = "";
      String getSchema = "";
      if (dbType.equals("postgresql")) {
         getSchema = "(DataSourceName=.*?currentSchema=)|(currentSchema=.*?DataSourceName=)";
      } else {
         getSchema = "(currentSchema=|SCHEMA=|applicationName=|mysql|oracle)";
      }

      Pattern pattern = Pattern.compile(getSchema, 2);

      for(Matcher matcher = pattern.matcher(url); matcher.find(); schema = matcher.group(0)) {
      }

      return schema;
   }

   @PassToken
   @ResponseBody
   @GetMapping({"/downloadLog"})
   public void download(HttpServletRequest request, HttpServletResponse response) {
      String id = request.getParameter("cLientId").toString();
      TCoreClientInfo tCoreClientInfo = (TCoreClientInfo)this.clientInfoDao.get(id);
      Date date = new Date(tCoreClientInfo.getErrorTime().getTime());
      SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HHmmss");
      String errorTime = sdf.format(date);
      String fileName = "errorlog_" + errorTime + ".log";
      response.setContentType("application/octet-stream;text/plain; charset=UTF-8");
      response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");

      OutputStream outputStream;
      try {
         outputStream = response.getOutputStream();
      } catch (IOException e) {
         throw new RuntimeException(e);
      }

      String responseText = errorTime + " " + tCoreClientInfo.getClientError();
      byte[] buffer = responseText.getBytes();

      try {
         outputStream.write(buffer, 0, buffer.length);
         outputStream.close();
      } catch (IOException e) {
         throw new RuntimeException(e);
      }
   }
}
