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

import com.chenyang.nse.bussiness.commmon.json.RespHelper;
import com.chenyang.nse.bussiness.commmon.json.Response;
import com.chenyang.nse.bussiness.config.PropertiesLoaderUtils;
import com.chenyang.nse.bussiness.dao.table.core.file.FileStructureGroupParam;
import com.chenyang.nse.bussiness.dto.FilestructureDTO;
import com.chenyang.nse.bussiness.entity.orm.table.core.TCoreDatasystem;
import com.chenyang.nse.bussiness.entity.orm.table.core.dataproject.TCoreFileSysGroup;
import com.chenyang.nse.bussiness.entity.orm.table.core.file.TCoreFileStructure;
import com.chenyang.nse.bussiness.entity.orm.table.core.file.TCoreFileStructureGroup;
import com.chenyang.nse.bussiness.entity.orm.table.core.file.TCoreFileStructurecolumn;
import com.chenyang.nse.bussiness.entity.orm.table.core.file.TCoreFileStructurespliter;
import com.chenyang.nse.bussiness.entity.orm.table.core.file.TCoreFileStructurewidth;
import com.chenyang.nse.bussiness.entity.orm.table.core.masking.TCoreMaskingFilesystem;
import com.chenyang.nse.bussiness.entity.param.filesystem.DemoFileImportParam;
import com.chenyang.nse.bussiness.entity.param.filesystem.FileDemoParam;
import com.chenyang.nse.bussiness.entity.vo.ComboboxVO;
import com.chenyang.nse.bussiness.entity.vo.ResultVO;
import com.chenyang.nse.bussiness.enumeration.file.CodePage;
import com.chenyang.nse.bussiness.enumeration.file.ColumnType;
import com.chenyang.nse.bussiness.enumeration.file.DateFormat;
import com.chenyang.nse.bussiness.enumeration.file.RowdeLimiter;
import com.chenyang.nse.bussiness.service.core.DataSystemService;
import com.chenyang.nse.bussiness.service.core.FileSystemService;
import com.chenyang.nse.bussiness.tools.jdbc.JdbcTool;
import com.chenyang.nse.bussiness.tools.msg.MesUtil;
import com.chenyang.nse.bussiness.tools.string.StringTool;
import com.chenyang.nse.bussiness.tools.token.TokenUtil;
import java.io.IOException;
import java.sql.Connection;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.Size;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
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.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping({"/core/filesystem"})
public class FileSystemController {
   private static final Logger ddmauditLogger = LoggerFactory.getLogger("ddmauditLogger");
   @Autowired
   private FileSystemService fileSystemService;
   @Autowired
   private DataSystemService dataSystemService;

   @RequestMapping
   public String index(HttpServletRequest request, HttpServletResponse response, Model model) {
      return "core/filesystem/filesystem";
   }

   @RequestMapping({"/structure/add"})
   @ResponseBody
   public Response structureadd(@Valid @RequestBody FilestructureDTO filestructureDTO, HttpServletRequest request, HttpServletResponse response, Model model) {
      this.fileSystemService.addFileStructure(filestructureDTO);
      return RespHelper.successResp();
   }

   @RequestMapping({"/structure/save"})
   @ResponseBody
   public Response structuresave(@RequestBody DemoFileImportParam param, HttpServletRequest request, HttpServletResponse response, Model model) {
      this.fileSystemService.addFileStructure(param);
      return RespHelper.successResp();
   }

   @RequestMapping({"/structure/dbinput"})
   @ResponseBody
   public void structuredbinput(@RequestParam Map<String, String> map) {
      this.fileSystemService.dbInputFileStructure(map);
   }

   @RequestMapping({"/structure/remove"})
   @ResponseBody
   public void structureremove(@RequestParam String id, HttpServletRequest request, HttpServletResponse response, Model model) {
      this.fileSystemService.removeFileStructure(id);
   }

   @RequestMapping({"/structure/modify"})
   @ResponseBody
   public void structuremodify(@RequestParam Map<String, String> map, HttpServletRequest request, HttpServletResponse response, Model model) {
      this.fileSystemService.modifyFileStructure(map);
   }

   @RequestMapping({"/structure/querysystem"})
   @ResponseBody
   public Response<List<TCoreFileStructure>> querysystem(HttpServletRequest request, HttpServletResponse response, Model model) {
      return RespHelper.<List<TCoreFileStructure>>successResp(this.fileSystemService.queryFileStructure());
   }

   @ResponseBody
   @PostMapping({"/saveFileStructureGroup"})
   public Response addFileStructureGroup(@Valid @RequestBody TCoreFileStructureGroup group, HttpServletRequest request) {
      String username = TokenUtil.getUserId(request.getHeader("token"));
      Boolean flag = this.fileSystemService.checkRepeatGroupName(group.getGroupname());
      if (flag) {
         this.fileSystemService.saveFileStructureGroup(group);
         if (null != group.getGroupname()) {
            MDC.put("module", "文件结构管理");
            MDC.put("time", (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date()));
            MDC.put("username", username);
            if (null != group.getId()) {
               MDC.put("code", "DDM_02555");
            } else {
               MDC.put("code", "DDM_02559");
            }
         }

         return RespHelper.successResp("保存成功");
      } else {
         return RespHelper.createResp(false, "500", "文件结构组名重复");
      }
   }

   @RequestMapping({"/structure/queryrepeatname"})
   @ResponseBody
   public Response<List<TCoreFileStructure>> queryrepeatname(@RequestParam("filestructurename[]") String[] filestructurename, @Size(max = 50) String filestructuregroup) {
      return RespHelper.<List<TCoreFileStructure>>successResp(this.fileSystemService.queryRepeatName(filestructurename, filestructuregroup));
   }

   @RequestMapping({"/structure/querystructurespliter"})
   @ResponseBody
   public Response<TCoreFileStructurespliter> querystructurespliter(@Size(max = 50) String filestructureid, HttpServletRequest request, HttpServletResponse response, Model model) {
      TCoreFileStructurespliter tCoreFileStructurespliter = this.fileSystemService.queryFileStructureSpliter(filestructureid);
      TCoreFileStructurespliter obj = new TCoreFileStructurespliter();
      obj.setConsecdelimitersasone(tCoreFileStructurespliter.getConsecdelimitersasone());
      obj.setDelimiterencoding(tCoreFileStructurespliter.getDelimiterencoding());
      obj.setEscapecharacter(tCoreFileStructurespliter.getEscapecharacter());
      obj.setFilestructureid(tCoreFileStructurespliter.getFilestructureid());
      obj.setKeepescapechar(tCoreFileStructurespliter.getKeepescapechar());
      obj.setMultidelimitersasand(tCoreFileStructurespliter.getMultidelimitersasand());
      obj.setQuotecharacter(tCoreFileStructurespliter.getQuotecharacter());
      obj.setRowdelimiter(tCoreFileStructurespliter.getRowdelimiter());
      obj.setId(tCoreFileStructurespliter.getId());
      if (tCoreFileStructurespliter.getDelimiters().equals("C")) {
         obj.setDelimiters(",");
      } else if (tCoreFileStructurespliter.getDelimiters().equals("T")) {
         obj.setDelimiters("\\011");
      } else if (tCoreFileStructurespliter.getDelimiters().equals("M")) {
         obj.setDelimiters(";");
      } else if (tCoreFileStructurespliter.getDelimiters().equals("P")) {
         obj.setDelimiters(" ");
      } else {
         obj.setDelimiters(tCoreFileStructurespliter.getDelimiters());
      }

      return RespHelper.<TCoreFileStructurespliter>successResp(obj);
   }

   @RequestMapping({"/structure/querystructurewidth"})
   @ResponseBody
   public TCoreFileStructurewidth querystructurewidth(String filestructureid, HttpServletRequest request, HttpServletResponse response, Model model) {
      return this.fileSystemService.queryFileStructureWidth(filestructureid);
   }

   @RequestMapping({"/structure/queryfilecolumn"})
   @ResponseBody
   public List<TCoreFileStructurecolumn> queryfilecolumn(String structureid, HttpServletRequest request, HttpServletResponse response, Model model) {
      return this.fileSystemService.queryFileStructureColumn(structureid);
   }

   @RequestMapping({"/structure/queryfilecolumnsearch"})
   @ResponseBody
   public Response<List<TCoreFileStructurecolumn>> queryfilecolumnsearch(@Size(max = 50) String structureid, @Size(max = 50) String datatypes, HttpServletRequest request, HttpServletResponse response, Model model) {
      return RespHelper.<List<TCoreFileStructurecolumn>>successResp(this.fileSystemService.queryFileStructureColumnSearch(structureid, datatypes));
   }

   @RequestMapping({"/structure/datawidthdouble"})
   @ResponseBody
   public void datawidthdouble(String structureid, String strtype, HttpServletRequest request, HttpServletResponse response, Model model) {
      this.fileSystemService.dataWidthDouble(structureid, strtype);
   }

   @PostMapping({"/structure/querycolumntype"})
   @ResponseBody
   public Response querycolumntype() {
      List<ComboboxVO> list = new ArrayList();

      for(ColumnType e : ColumnType.values()) {
         ComboboxVO c = new ComboboxVO(e.getName());
         list.add(c);
      }

      return RespHelper.successResp(list);
   }

   @ResponseBody
   @RequestMapping({"/delFileStructureGroup"})
   public Response delFileStructureGroup(@Valid @RequestBody FileStructureGroupParam param, HttpServletRequest request) {
      String username = TokenUtil.getUserId(request.getHeader("token"));
      if (null != param.getGroupname()) {
         MDC.put("module", "文件结构管理");
         MDC.put("time", (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date()));
         MDC.put("username", username);
         MDC.put("code", "DDM_02999");
         ddmauditLogger.info(MesUtil.getMsg("DDM_02999", new String[]{username, param.getGroupname()}));
      }

      String groupid = param.getGroupid();
      String groupname = param.getGroupname();
      List<TCoreFileSysGroup> coreFileSysGroupList = this.dataSystemService.queryByGroupid(groupname);
      if (coreFileSysGroupList.size() > 0) {
         return RespHelper.createResp(false, "600", "文件结构组名被资产库使用");
      } else {
         this.fileSystemService.delFileStructureGroup(groupid, groupname);
         return RespHelper.successResp("操作成功");
      }
   }

   @RequestMapping({"/structure/querygroupnameByid"})
   @ResponseBody
   public List<ComboboxVO> querygroupnameByid(String filesourceid) {
      return this.fileSystemService.queryGroupnameBySysid(filesourceid);
   }

   @RequestMapping({"/structure/querycodepage"})
   @ResponseBody
   public Response<List<ComboboxVO>> querycodepage(HttpServletRequest request, HttpServletResponse response, Model model) {
      List<ComboboxVO> list = new ArrayList();

      for(CodePage cp : CodePage.values()) {
         ComboboxVO c = new ComboboxVO(cp.getFlag(), cp.getName());
         list.add(c);
      }

      return RespHelper.<List<ComboboxVO>>successResp(list);
   }

   @RequestMapping({"/structure/querygroupname"})
   @ResponseBody
   public Response<List<ComboboxVO>> querygroupname() {
      return RespHelper.<List<ComboboxVO>>successResp(this.fileSystemService.queryGroupname());
   }

   @RequestMapping({"/structure/queryrowdelimiter"})
   @ResponseBody
   public Response<List<ComboboxVO>> queryrowdelimiter(HttpServletRequest request, HttpServletResponse response, Model model) {
      List<ComboboxVO> list = new ArrayList();

      for(RowdeLimiter r : RowdeLimiter.values()) {
         ComboboxVO c = new ComboboxVO(r.getFlag(), r.getName());
         list.add(c);
      }

      ComboboxVO c = new ComboboxVO("0", "无");
      list.add(c);
      return RespHelper.<List<ComboboxVO>>successResp(list);
   }

   @ResponseBody
   @PostMapping({"/formattitle"})
   public Response formattitle(@Valid @RequestBody(required = false) FileDemoParam param) {
      List<List<String>> data = new ArrayList();
      List<String> filecontent = param.getTitle();
      if ("D".equals(param.getSeparatetype())) {
         String s = param.getSeparate();
         String separate = null;
         switch (s) {
            case "T":
               separate = "\t";
               break;
            case "M":
               separate = ";";
               break;
            case "C":
               separate = ",";
               break;
            case "P":
               separate = " ";
               break;
            default:
               separate = param.getSeparatestring();
         }

         String l = param.getLimit();
         String limit = null;
         switch (l) {
            case "S":
               limit = "'";
               break;
            case "D":
               limit = "\"";
               break;
            default:
               limit = "";
         }

         String escepe = param.getEscape();
         String series = param.getSeries();
         if (null == param.getMulti()) {
            param.setMulti("");
         }

         boolean multi = param.getMulti().equals("1");
         if ("other".equals(s)) {
            for(String str : filecontent) {
               data.add(StringTool.splitString(str, separate, multi, escepe, limit));
            }
         } else {
            for(String str : filecontent) {
               data.add(StringTool.splitString(str, separate, true, escepe, limit));
            }
         }
      } else {
         String w = param.getWidthstring();
         if (w != null && !"".equals(w)) {
            String[] arr = w.split(",");
            List<String> l = Arrays.asList(arr);
            Collections.sort(l, new Comparator<String>() {
               public int compare(String s1, String s2) {
                  int i1 = Integer.valueOf(s1);
                  int i2 = Integer.valueOf(s2);
                  if (i1 < i2) {
                     return -1;
                  } else {
                     return i1 > i2 ? 1 : 0;
                  }
               }
            });
            int ws = 0;
            List<String> sp = new ArrayList();

            for(int i = 0; i < l.size(); ++i) {
               if (i == 0) {
                  sp.add(String.valueOf(Integer.valueOf((String)l.get(i)) + 1));
                  ws += Integer.valueOf((String)l.get(i)) + 1;
               } else {
                  sp.add(String.valueOf(Integer.valueOf((String)l.get(i)) - Integer.valueOf((String)l.get(i - 1))));
                  ws += Integer.valueOf((String)l.get(i)) - Integer.valueOf((String)l.get(i - 1));
               }
            }

            for(String str : filecontent) {
               sp.add(String.valueOf(str.length() - ws));
               data.add(StringTool.widthSpliter(str, sp));
            }
         } else {
            for(String str : filecontent) {
               List<String> temp = new ArrayList();
               temp.add(str);
               data.add(temp);
            }
         }
      }

      List<TCoreFileStructurecolumn> field = new ArrayList();
      List<String> l = (List)data.get(0);

      for(int i = 0; i < l.size(); ++i) {
         TCoreFileStructurecolumn temp = new TCoreFileStructurecolumn(i, (String)l.get(i), ColumnType.STRING.getName(), String.valueOf(((String)l.get(i)).length()), "0", String.valueOf(((String)l.get(i)).length() == 0 ? 1 : ((String)l.get(i)).length()), "", "YES", "NO", (String)null);
         if (null != param.getFirsttitlerow() && param.getFirsttitlerow().equals("0")) {
            temp.setColumnname("Field" + i);
         }

         field.add(temp);
      }

      return RespHelper.successResp(field);
   }

   @RequestMapping({"/structure/querydateformat"})
   @ResponseBody
   public Response<List<ComboboxVO>> querydateformat(HttpServletRequest request, HttpServletResponse response, Model model) {
      List<ComboboxVO> list = new ArrayList();

      for(DateFormat df : DateFormat.values()) {
         ComboboxVO c = new ComboboxVO(df.getName());
         list.add(c);
      }

      return RespHelper.<List<ComboboxVO>>successResp(list);
   }

   @RequestMapping({"/querydatasystem"})
   @ResponseBody
   public List<TCoreDatasystem> querydatasystem() {
      String flag = "1";
      List<TCoreDatasystem> list = this.dataSystemService.query(flag);
      return list;
   }

   @RequestMapping({"/queryschema"})
   @ResponseBody
   public List<ComboboxVO> queryschema(String datasystemid, HttpServletRequest request, HttpServletResponse response, Model model) {
      Connection conn = this.dataSystemService.getConnectionByDataSystemId(datasystemid);
      List<String> schema = JdbcTool.getDbSchemas(conn);
      JdbcTool.closeConnection(conn);
      List<ComboboxVO> list = new ArrayList();

      for(String str : schema) {
         ComboboxVO cv = new ComboboxVO(str);
         list.add(cv);
      }

      return list;
   }

   @RequestMapping({"/querytablelist"})
   @ResponseBody
   public List<ComboboxVO> querytablelist(String datasystemid, String schema) {
      Connection conn = this.dataSystemService.getConnectionByDataSystemId(datasystemid);
      List<String> table = JdbcTool.getAllTableName(conn, schema);
      JdbcTool.closeConnection(conn);
      List<ComboboxVO> list = new ArrayList();

      for(String str : table) {
         ComboboxVO c = new ComboboxVO(str);
         list.add(c);
      }

      return list;
   }

   @RequestMapping({"/createstep"})
   public String createstep(String type) {
      return "core/filesystem/" + type + "/createstep";
   }

   @RequestMapping({"/nextstep"})
   public String nextstep(String type, String step, HttpServletRequest request, HttpServletResponse response, Model model) {
      Properties props = new Properties();

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

      String enginetype = props.getProperty("masking_engine_type");
      model.addAttribute("enginetype", enginetype);
      return "core/filesystem/" + type + "/" + step;
   }

   @ResponseBody
   @RequestMapping({"/formatdata"})
   public Response<List<List<String>>> formatdata(@Valid @RequestBody FileDemoParam param, HttpServletRequest request, HttpServletResponse response, Model model) {
      List<List<String>> data = new ArrayList();
      List<String> filecontent = param.getTitle();
      if ("D".equals(param.getSeparatetype())) {
         String s = param.getSeparate();
         String separate = null;
         switch (s) {
            case "T":
               separate = "\t";
               break;
            case "M":
               separate = ";";
               break;
            case "C":
               separate = ",";
               break;
            case "P":
               separate = " ";
               break;
            default:
               separate = param.getSeparatestring();
         }

         String l = param.getLimit();
         String limit = null;
         switch (l) {
            case "S":
               limit = "'";
               break;
            case "D":
               limit = "\"";
               break;
            default:
               limit = "";
         }

         String escepe = param.getEscape();
         String series = param.getSeries();
         boolean multi = null != param.getMulti() && param.getMulti().equals("1");
         if ("O".equals(s)) {
            for(String str : filecontent) {
               data.add(StringTool.splitString(str, separate, multi, escepe, limit));
            }
         } else {
            for(String str : filecontent) {
               data.add(StringTool.splitString(str, separate, true, escepe, limit));
            }
         }
      } else {
         String w = param.getWidthstring();
         if (w != null && !"".equals(w)) {
            String[] arr = w.split(",");
            List<String> l = Arrays.asList(arr);
            Collections.sort(l, new Comparator<String>() {
               public int compare(String s1, String s2) {
                  int i1 = Integer.valueOf(s1);
                  int i2 = Integer.valueOf(s2);
                  if (i1 < i2) {
                     return -1;
                  } else {
                     return i1 > i2 ? 1 : 0;
                  }
               }
            });

            for(String str : filecontent) {
               data.add(StringTool.widthSpliter(str, l));
            }
         } else {
            for(String str : filecontent) {
               List<String> temp = new ArrayList();
               temp.add(str);
               data.add(temp);
            }
         }
      }

      return RespHelper.<List<List<String>>>successResp(data);
   }

   @RequestMapping({"/ismaskingtask"})
   @ResponseBody
   public ResultVO ismaskingtask(String structureid) {
      List<TCoreMaskingFilesystem> list = this.fileSystemService.queryMaskingTaskStructure(structureid);
      return list.size() == 0 ? new ResultVO("", true) : new ResultVO("", false);
   }
}
