package com.chenyang.nse.bussiness.webtools.controller.core;

import cn.hutool.core.lang.UUID;
import com.chenyang.nse.bussiness.config.PropertiesLoaderUtils;
import com.chenyang.nse.bussiness.webtools.entity.vo.DatabaseVO;
import com.chenyang.nse.bussiness.webtools.entity.vo.DatasystemVO;
import com.chenyang.nse.bussiness.webtools.entity.vo.ResultVO;
import com.chenyang.nse.bussiness.webtools.enumeration.EdbType;
import com.chenyang.nse.bussiness.webtools.json.ErrCode;
import com.chenyang.nse.bussiness.webtools.json.RespHelper;
import com.chenyang.nse.bussiness.webtools.json.Response;
import com.chenyang.nse.bussiness.webtools.tools.ip.IpUtil;
import com.chenyang.nse.bussiness.webtools.tools.jdbc.JdbcTool;
import com.chenyang.nse.bussiness.webtools.tools.jdbc.KafkaTool;
import com.chenyang.nse.bussiness.webtools.tools.redis.CacheUtil;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ui.Model;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping({"/webtools/core/database"})
public class WebToolsDatabaseController {
   private static Logger logger = LoggerFactory.getLogger(WebToolsDatabaseController.class);

   @ResponseBody
   @RequestMapping(
      value = {"/queryByFingerprint"},
      method = {RequestMethod.POST}
   )
   public Response<List<DatabaseVO>> findDatabaseVOByFingerprint(@RequestBody DatabaseVO databaseVO) {
      String fingerprint = databaseVO.getFingerprint();
      ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
      List<DatabaseVO> result = new ArrayList();

      Response var20;
      try {
         Properties props = new Properties();

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

         String databaselink = props.getProperty("databaselink");
         rwl.readLock().lock();
         if (StringUtils.isBlank(databaselink)) {
            databaselink = "/home/ghca/data";
         }

         FileReader fr = new FileReader(databaselink + "/database_file.txt");
         BufferedReader br = new BufferedReader(fr);

         for(String temp = br.readLine(); temp != null; temp = br.readLine()) {
            if (!temp.equals("")) {
               String[] infos = temp.split(",");
               if (infos[1].equals(fingerprint)) {
                  result.add(new DatabaseVO(infos[0], infos[1], infos[2], infos[3], infos[4], infos[5], infos[6], infos[7], infos[8]));
               }
            }
         }

         br.close();
         fr.close();
         return RespHelper.<List<DatabaseVO>>successResp(result);
      } catch (FileNotFoundException ex) {
         ex.printStackTrace();
         var20 = RespHelper.exceptionResp((Exception)ex);
      } catch (IOException ex) {
         ex.printStackTrace();
         var20 = RespHelper.exceptionResp((Exception)ex);
         return var20;
      } finally {
         rwl.readLock().unlock();
      }

      return var20;
   }

   @ResponseBody
   @RequestMapping(
      value = {"/queryAll"},
      method = {RequestMethod.POST}
   )
   public Response<ArrayList<DatabaseVO>> queryAll() {
      ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
      ArrayList<DatabaseVO> result = new ArrayList();

      Response var18;
      try {
         Properties props = new Properties();

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

         String databaselink = props.getProperty("databaselink");
         rwl.readLock().lock();
         FileReader fr = new FileReader(databaselink + "/database_file.txt");
         BufferedReader br = new BufferedReader(fr);

         for(String temp = br.readLine(); temp != null; temp = br.readLine()) {
            if (!temp.equals("")) {
               String[] infos = temp.split(",");
               result.add(new DatabaseVO(infos[0], infos[1], infos[2], infos[3], infos[4], infos[5], infos[6], infos[7], infos[8]));
            }
         }

         br.close();
         fr.close();
         return RespHelper.<ArrayList<DatabaseVO>>successResp(result);
      } catch (FileNotFoundException ex) {
         ex.printStackTrace();
         var18 = RespHelper.exceptionResp((Exception)ex);
      } catch (IOException ex) {
         ex.printStackTrace();
         var18 = RespHelper.exceptionResp((Exception)ex);
         return var18;
      } finally {
         rwl.readLock().unlock();
      }

      return var18;
   }

   @ResponseBody
   @RequestMapping(
      value = {"/login"},
      method = {RequestMethod.POST}
   )
   public Response testConnectOnAddOrEdit(@RequestBody DatabaseVO datasource, HttpServletRequest request, HttpServletResponse response, Model model) {
      Response res = RespHelper.successRespObj();
      ResultVO resultvo = new ResultVO();
      DatasystemVO datasystem = new DatasystemVO();
      datasystem.setDbip(datasource.getHost());
      datasystem.setDbport(datasource.getPort());
      datasystem.setDbschema(datasource.getSchema());
      datasystem.setDbservername(datasource.getSchema());
      datasystem.setDbtype(datasource.getDbtype());
      datasystem.setServername(datasource.getSchema());
      datasystem.setUsername(datasource.getUsername());
      datasystem.setPassword(datasource.getPassword());
      if (EdbType.KAFKA.getDbname().equals(datasource.getDbtype())) {
         new ResultVO("连接成功!", true);
         resultvo = KafkaTool.conntest(datasource.getHost(), Integer.parseInt(datasource.getPort()));
         res.setFlag(resultvo.getResult());
         res.setMsg(resultvo.getMessage());
         return res;
      } else {
         if (!"MONGODB".equals(datasource.getDbtype())) {
            if ("LOCALFILE".equals(datasource.getDbtype())) {
               resultvo.setResult(true);
               res.setFlag(resultvo.getResult());
               res.setMsg(resultvo.getMessage());
               return res;
            }

            boolean result = true;
            String url = "";
            if (datasource.getDbtype().equals("POSTGRESQL")) {
               datasource.setDbtype("GREENPLUM");
            }

            String driver = EdbType.getEdbTypeByDbcode(datasource.getDbtype()).getDbdriver();
            switch (datasource.getDbtype()) {
               case "INFORMIX":
                  url = EdbType.getUrlByEdbcode(datasource.getDbtype(), datasource.getHost(), datasource.getPort(), datasource.getSchema(), datasource.getSchema());
                  break;
               case "AS400":
                  url = EdbType.getUrlByEdbcode(datasource.getDbtype(), datasource.getHost(), datasource.getSchema(), datasource.getSchema());
                  break;
               default:
                  if (StringUtils.isNotBlank(datasource.getHost())) {
                     url = EdbType.getUrlByEdbcode(datasource.getDbtype(), datasource.getHost(), datasource.getPort(), datasource.getSchema());
                  }
            }

            StringBuffer msg = new StringBuffer();
            if (!"ORACLE".equals(datasource.getDbtype())) {
               resultvo = JdbcTool.testConnect(url, driver, datasource.getUsername(), datasource.getPassword());
            } else {
               url = EdbType.getUrlByEdbcode("ORACLE", datasource.getHost(), datasource.getPort(), datasource.getSchema());
               resultvo = JdbcTool.testConnect(url, driver, datasource.getUsername(), datasource.getPassword());
               this.appendServiceMsg(msg, resultvo, datasource);
            }

            if ("ORACLE".equals(datasource.getDbtype()) && StringUtils.isNotBlank(msg.toString())) {
               resultvo.setMessage(msg.toString());
            }

            result = resultvo.getResult();
            if (!result || StringUtils.isNotBlank(resultvo.getMessage())) {
               res.setFlag(false);
               res.setMsg(resultvo.getMessage());
               return res;
            }

            Connection conn = JdbcTool.getConnection(datasystem);
            if (conn != null) {
               result = true;
               CacheUtil.put(genCacheKey(datasource), conn);
            } else {
               result = false;
            }

            if (!result) {
               return RespHelper.errResp(ErrCode.LOGIN_ERROR_CODE);
            }
         }

         res.setFlag(resultvo.getResult());
         res.setMsg(resultvo.getMessage());
         return res;
      }
   }

   private void appendServiceMsg(StringBuffer msg, ResultVO resultvo, DatabaseVO datasource) {
      if (!ObjectUtils.isEmpty(resultvo) && !resultvo.getResult() && StringUtils.isNotBlank(resultvo.getMessage())) {
         msg.append("数据库[").append(datasource.getSchema()).append("]连接不通").append("[ip: ").append(datasource.getHost()).append("]").append("[port: ").append(datasource.getPort()).append("]").append(resultvo.getMessage());
      }

   }

   private boolean checkDatabaseIsExist(String id) {
      boolean result = false;

      try {
         Properties props = new Properties();

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

         String databaselink = props.getProperty("databaselink");
         FileReader fr = new FileReader(databaselink + "/database_file.txt");
         BufferedReader br = new BufferedReader(fr);

         for(String temp = br.readLine(); temp != null; temp = br.readLine()) {
            if (!temp.equals("")) {
               String[] infos = temp.split(",");
               if (infos[0].equals(id)) {
                  result = true;
                  break;
               }
            }
         }

         br.close();
         fr.close();
         return result;
      } catch (FileNotFoundException ex) {
         ex.printStackTrace();
         return result;
      } catch (IOException ex) {
         ex.printStackTrace();
         return result;
      }
   }

   @ResponseBody
   @RequestMapping(
      value = {"/add"},
      method = {RequestMethod.POST}
   )
   public Response add(@RequestBody DatabaseVO databaseVO) {
      ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

      Response var17;
      try {
         Properties props = new Properties();

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

         String databaselink = props.getProperty("databaselink");
         rwl.writeLock().lock();
         FileWriter fw = new FileWriter(databaselink + "/database_file.txt", true);
         BufferedWriter bw = new BufferedWriter(fw);
         StringBuffer str = new StringBuffer();
         str.append(UUID.randomUUID() + ",");
         str.append(databaseVO.getFingerprint() + ",");
         str.append(databaseVO.getHost() + ",");
         str.append(databaseVO.getSchema() + ",");
         str.append(databaseVO.getPort() + ",");
         str.append(databaseVO.getUsername() + ",");
         str.append(databaseVO.getPassword() + ",");
         str.append(databaseVO.getDbtype() + ",");
         str.append(databaseVO.getDatasystemname());
         bw.newLine();
         bw.write(str.toString());
         bw.close();
         fw.close();
         return RespHelper.successResp();
      } catch (FileNotFoundException ex) {
         ex.printStackTrace();
         var17 = RespHelper.errResp(ErrCode.ADD_ERROR_CODE);
      } catch (IOException ex) {
         ex.printStackTrace();
         var17 = RespHelper.errResp(ErrCode.ADD_ERROR_CODE);
         return var17;
      } finally {
         rwl.writeLock().unlock();
      }

      return var17;
   }

   @ResponseBody
   @RequestMapping(
      value = {"/remove"},
      method = {RequestMethod.POST}
   )
   public Response delById(@RequestBody DatabaseVO databaseVO) {
      String id = databaseVO.getId();
      if (StringUtils.isBlank(id)) {
         return RespHelper.paramErrResp();
      } else {
         ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
         if (this.checkDatabaseIsExist(id)) {
            ArrayList<DatabaseVO> databaseVOs = this.findAllDatabases();

            for(int i = 0; i < databaseVOs.size(); ++i) {
               DatabaseVO temp = (DatabaseVO)databaseVOs.get(i);
               if (temp.getId().equals(id)) {
                  databaseVOs.remove(temp);
               }
            }

            Response var23;
            try {
               Properties props = new Properties();

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

               String databaselink = props.getProperty("databaselink");
               rwl.writeLock().lock();
               FileWriter fw = new FileWriter(databaselink + "/database_file.txt");
               BufferedWriter bw = new BufferedWriter(fw);

               for(int i = 0; i < databaseVOs.size(); ++i) {
                  DatabaseVO temp = (DatabaseVO)databaseVOs.get(i);
                  StringBuffer str = new StringBuffer();
                  str.append(UUID.randomUUID() + ",");
                  str.append(temp.getFingerprint() + ",");
                  str.append(temp.getHost() + ",");
                  str.append(temp.getSchema() + ",");
                  str.append(temp.getPort() + ",");
                  str.append(temp.getUsername() + ",");
                  str.append(temp.getPassword() + ",");
                  str.append(temp.getDbtype() + ",");
                  str.append(temp.getDatasystemname());
                  bw.write(str.toString());
                  bw.newLine();
               }

               bw.close();
               fw.close();
               return RespHelper.successResp();
            } catch (FileNotFoundException ex) {
               ex.printStackTrace();
               var23 = RespHelper.errResp(ErrCode.DELETE_ERROR_CODE);
            } catch (IOException ex) {
               ex.printStackTrace();
               var23 = RespHelper.errResp(ErrCode.DELETE_ERROR_CODE);
               return var23;
            } finally {
               rwl.writeLock().unlock();
            }

            return var23;
         } else {
            return RespHelper.successResp();
         }
      }
   }

   public ArrayList<DatabaseVO> findAllDatabases() {
      ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
      ArrayList<DatabaseVO> result = new ArrayList();

      try {
         Properties props = new Properties();

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

         String databaselink = props.getProperty("databaselink");
         rwl.readLock().lock();
         FileReader fr = new FileReader(databaselink + "/database_file.txt");
         BufferedReader br = new BufferedReader(fr);

         for(String temp = br.readLine(); temp != null; temp = br.readLine()) {
            if (!temp.equals("")) {
               String[] infos = temp.split(",");
               result.add(new DatabaseVO(infos[0], infos[1], infos[2], infos[3], infos[4], infos[5], infos[6], infos[7], infos[8]));
            }
         }

         br.close();
         fr.close();
      } catch (FileNotFoundException ex) {
         ex.printStackTrace();
      } catch (IOException ex) {
         ex.printStackTrace();
      } finally {
         rwl.readLock().unlock();
      }

      return result;
   }

   @ResponseBody
   @RequestMapping(
      value = {"/edit"},
      method = {RequestMethod.POST}
   )
   public Response updateDatabaseVO(@RequestBody DatabaseVO databaseVO) {
      if (StringUtils.isBlank(databaseVO.getId())) {
         return RespHelper.paramErrResp();
      } else {
         return this.addDatabaseVO(databaseVO) ? RespHelper.successResp() : RespHelper.errResp(ErrCode.UPDATE_ERROR_CODE);
      }
   }

   @ResponseBody
   @RequestMapping(
      value = {"/getClientIp"},
      method = {RequestMethod.POST}
   )
   public Response getClientIp(@RequestBody DatabaseVO databaseVO, HttpServletRequest request) {
      return RespHelper.successResp(IpUtil.getOuterNetIp(request));
   }

   public Boolean addDatabaseVO(DatabaseVO databaseVO) {
      Boolean result = false;
      ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
      if (this.checkDatabaseIsExist(databaseVO.getId())) {
         ArrayList<DatabaseVO> databaseVOs = this.findAllDatabases();

         for(int i = 0; i < databaseVOs.size(); ++i) {
            DatabaseVO temp = (DatabaseVO)databaseVOs.get(i);
            if (temp.getId().equals(databaseVO.getId())) {
               ((DatabaseVO)databaseVOs.get(i)).setFingerprint(databaseVO.getFingerprint());
               ((DatabaseVO)databaseVOs.get(i)).setHost(databaseVO.getHost());
               ((DatabaseVO)databaseVOs.get(i)).setSchema(databaseVO.getSchema());
               ((DatabaseVO)databaseVOs.get(i)).setPort(databaseVO.getPort());
               ((DatabaseVO)databaseVOs.get(i)).setUsername(databaseVO.getUsername());
               ((DatabaseVO)databaseVOs.get(i)).setPassword(databaseVO.getPassword());
               ((DatabaseVO)databaseVOs.get(i)).setDbtype(databaseVO.getDbtype());
               ((DatabaseVO)databaseVOs.get(i)).setDatasystemname(databaseVO.getDatasystemname());
            }
         }

         try {
            Properties props = new Properties();

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

            String databaselink = props.getProperty("databaselink");
            rwl.writeLock().lock();
            FileWriter fw = new FileWriter(databaselink + "/database_file.txt");
            BufferedWriter bw = new BufferedWriter(fw);

            for(int i = 0; i < databaseVOs.size(); ++i) {
               DatabaseVO temp = (DatabaseVO)databaseVOs.get(i);
               StringBuffer str = new StringBuffer();
               str.append(UUID.randomUUID() + ",");
               str.append(temp.getFingerprint() + ",");
               str.append(temp.getHost() + ",");
               str.append(temp.getSchema() + ",");
               str.append(temp.getPort() + ",");
               str.append(temp.getUsername() + ",");
               str.append(temp.getPassword() + ",");
               str.append(temp.getDbtype() + ",");
               str.append(temp.getDatasystemname());
               bw.write(str.toString());
               bw.newLine();
            }

            bw.close();
            fw.close();
            result = true;
         } catch (FileNotFoundException ex) {
            ex.printStackTrace();
         } catch (IOException ex) {
            ex.printStackTrace();
         } finally {
            rwl.writeLock().unlock();
         }
      }

      return result;
   }

   @ResponseBody
   @RequestMapping(
      value = {"/testConn"},
      method = {RequestMethod.POST}
   )
   public Response testConn(@RequestBody DatabaseVO datasource, HttpServletRequest request, HttpServletResponse response, Model model) {
      Response res = RespHelper.successResp();
      ResultVO resultvo = new ResultVO();
      if (!"MONGODB".equals(datasource.getDbtype())) {
         boolean result = true;
         String url = "";
         if (datasource.getDbtype().equals("POSTGRESQL")) {
            datasource.setDbtype("GREENPLUM");
         }

         String driver = EdbType.getEdbTypeByDbcode(datasource.getDbtype()).getDbdriver();
         switch (datasource.getDbtype()) {
            case "INFORMIX":
               url = EdbType.getUrlByEdbcode(datasource.getDbtype(), datasource.getHost(), datasource.getPort(), datasource.getSchema(), datasource.getSchema());
               break;
            case "AS400":
               url = EdbType.getUrlByEdbcode(datasource.getDbtype(), datasource.getHost(), datasource.getSchema(), datasource.getSchema());
               break;
            default:
               if (StringUtils.isNotBlank(datasource.getHost())) {
                  url = EdbType.getUrlByEdbcode(datasource.getDbtype(), datasource.getHost(), datasource.getPort(), datasource.getSchema());
               }
         }

         StringBuffer msg = new StringBuffer();
         resultvo = JdbcTool.testConnect(url, driver, datasource.getUsername(), datasource.getPassword());
         if ("ORACLE".equals(datasource.getDbtype()) && StringUtils.isNotBlank(msg.toString())) {
            resultvo.setMessage(msg.toString());
         }

         result = resultvo.getResult();
         if (!result || StringUtils.isNotBlank(resultvo.getMessage())) {
            res.setData(false);
            res.setMsg(resultvo.getMessage());
            return res;
         }
      }

      res.setData(resultvo.getResult());
      res.setMsg(resultvo.getMessage());
      return res;
   }

   @ResponseBody
   @RequestMapping(
      value = {"/quit"},
      method = {RequestMethod.POST}
   )
   public Response closeConn(@RequestBody DatabaseVO datasource) {
      Boolean result = false;
      if (CacheUtil.exists(genCacheKey(datasource))) {
         Connection conn = (Connection)CacheUtil.getCacheValue(genCacheKey(datasource));
         if (conn != null) {
            try {
               conn.close();
               result = true;
            } catch (SQLException e) {
               e.printStackTrace();
            }
         }

         CacheUtil.delCacheValue(genCacheKey(datasource));
      }

      return !result ? RespHelper.errResp(ErrCode.LOGINOUT_ERROR_CODE) : RespHelper.successResp();
   }

   private static String genCacheKey(DatabaseVO datasource) {
      return datasource.getFingerprint() + "_" + datasource.getHost() + "_" + datasource.getPort() + "_" + datasource.getUsername();
   }
}
