package com.chenyang.nse.bussiness.tools.dmp;

import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import com.chenyang.nse.bussiness.config.PropertiesLoaderUtils;
import com.chenyang.nse.bussiness.entity.vo.maskingtask.ColumnInfoVO;
import com.chenyang.nse.bussiness.tools.command.CommandTool;
import com.chenyang.nse.bussiness.tools.datatime.DateTime1Tool;
import com.chenyang.nse.bussiness.tools.io.FileTool;
import com.chenyang.nse.bussiness.tools.xml.XmlTool;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.lang.StringUtils;

public class MultipleDmpTool {
   public static final int arraySize = 10000;
   public static final int READ_LINE_OA_CNT = 5000;
   public static final String STR_DATA_SEPARATOR = XmlTool.getFileValue("ORACLE/db-sourcedelimiter");
   public static final int INT_READ_LINE_CNT = 5000;

   private static StringBuffer parsingDataByLine(List<String> colTypeList, String contents10, String split, String doubleQuotationFlg) {
      StringBuffer sb = new StringBuffer();
      String sourcequoteCharacter = "2";
      if (!"1".equals(doubleQuotationFlg)) {
         sourcequoteCharacter = "";
      } else if ("2".equals(sourcequoteCharacter)) {
         sourcequoteCharacter = "\"";
      } else if ("1".equals(sourcequoteCharacter)) {
         sourcequoteCharacter = "'";
      } else {
         sourcequoteCharacter = "";
      }

      String dataSeparator = STR_DATA_SEPARATOR;

      try {
         String[] content_sz = contents10.split(split);
         Integer[] intLineArr = new Integer[content_sz.length];

         for(int i = 0; i < content_sz.length; ++i) {
            intLineArr[i] = Integer.valueOf(content_sz[i]);
         }

         int content_length = intLineArr.length;
         int point = 0;

         for(int colIndex = 0; point < content_length; ++point) {
            if (content_sz[point].equals("0")) {
               String content16 = "";
               int zd_length = intLineArr[point - 1];
               ++point;
               List<Integer> intColList = new ArrayList();

               for(int j = point; j < point + zd_length; ++j) {
                  content16 = content16 + content_sz[j] + ",";
                  intColList.add(intLineArr[j]);
               }

               String colType = (String)colTypeList.get(colIndex);
               colType = colType.trim();
               sb.append(sourcequoteCharacter);
               if (!colType.equalsIgnoreCase("VARCHAR2") && !colType.equalsIgnoreCase("CHAR")) {
                  if (!colType.equalsIgnoreCase("NVARCHAR2") && !colType.equalsIgnoreCase("NCHAR")) {
                     if (!colType.equals("NUMBER") && !colType.equalsIgnoreCase("float")) {
                        if (colType.equalsIgnoreCase("LONG")) {
                           sb.append(lNumberParsing(intColList));
                        } else if (colType.equals("DATE")) {
                           sb.append(dateParsing(intColList));
                        } else if (colType.equalsIgnoreCase("TIMESTAMP")) {
                           sb.append(timestampParsing(intColList));
                        }
                     } else {
                        sb.append(numberParsing(intColList));
                     }
                  } else {
                     sb.append(nStringToGbk(intColList));
                  }
               } else {
                  sb.append(stringToGbk(intColList));
               }

               sb.append(sourcequoteCharacter);
               sb.append(dataSeparator);
               point += zd_length - 1;
               ++colIndex;
            }

            if (content_sz[point].equals("255") && content_sz[point - 1].equals("254")) {
               sb.append(dataSeparator);
               ++point;
               ++colIndex;
            }
         }

         sb.append("\r\n");
      } catch (Exception e) {
         e.printStackTrace();
      }

      return sb;
   }

   private static String stringToGbk(List<Integer> intColLst) {
      String result = "";

      try {
         byte[] byteArr = new byte[intColLst.size()];

         for(int i = 0; i < intColLst.size(); ++i) {
            byteArr[i] = (byte)((Integer)intColLst.get(i) & 255);
         }

         result = new String(byteArr, "gbk");
      } catch (UnsupportedEncodingException e) {
         e.printStackTrace();
      }

      return result;
   }

   private static String nStringToGbk(List<Integer> intColLst) {
      String result = "";
      int j = 0;

      try {
         if (0 == (Integer)intColLst.get(0)) {
            byte[] byteArr = new byte[intColLst.size() / 2];

            for(int i = 0; i < intColLst.size(); ++i) {
               if (i % 2 != 0) {
                  byteArr[j] = (byte)((Integer)intColLst.get(i) & 255);
                  ++j;
               }
            }

            result = new String(byteArr, "gbk");
         } else {
            byte[] byteArr = new byte[intColLst.size()];

            for(int i = 0; i < intColLst.size(); ++i) {
               byteArr[i] = (byte)((Integer)intColLst.get(i) & 255);
            }

            result = new String(byteArr, "utf-16");
         }
      } catch (UnsupportedEncodingException e) {
         e.printStackTrace();
      }

      return result;
   }

   private static String dateParsing(List<Integer> intColLst) {
      String datefmt = "yyyy-MM-dd HH:mm:ss";
      Calendar calendar = Calendar.getInstance();
      int[] date = new int[6];
      String reStr = "";

      for(int i = 0; i < intColLst.size(); ++i) {
         int sz = (Integer)intColLst.get(i);
         if (i == 0 || i == 1) {
            sz -= 100;
         }

         reStr = reStr + String.format("%02d", sz);
         if (i != 0) {
            date[i - 1] = Integer.parseInt(reStr);
            reStr = "";
         }
      }

      calendar.set(date[0], date[1] - 1, date[2], date[3] - 1, date[4] - 1, date[5] - 1);
      SimpleDateFormat sdf = new SimpleDateFormat(datefmt);
      String dateStr = sdf.format(calendar.getTime());
      return dateStr;
   }

   private static String timestampParsing(List<Integer> intColList) {
      List<Integer> subColList1 = intColList.subList(0, 7);
      String dateStr = dateParsing(subColList1);
      List<Integer> subColList2 = intColList.subList(7, intColList.size());
      if (null != subColList2 && subColList2.size() > 0) {
         String content16MsPart = "";

         for(int i = 0; i < subColList2.size(); ++i) {
            content16MsPart = content16MsPart + Integer.toHexString((Integer)subColList2.get(i));
         }

         int intStr = DmpCommonTool.binary16_10(content16MsPart);
         dateStr = dateStr + "." + intStr;
      }

      return dateStr;
   }

   private static String numberParsing(List<Integer> intColLst) {
      int prefixNum = (Integer)intColLst.get(0);
      int ws = prefixNum - 192;
      String reInt = "";
      if (ws >= 0) {
         int idx = prefixNum - 193;
         intColLst.remove(0);

         while(intColLst.size() < idx + 1) {
            intColLst.add(1);
         }

         BigDecimal reDouble = new BigDecimal(0);

         for(int i = 0; i < intColLst.size(); ++i) {
            int codeInt = (Integer)intColLst.get(i);
            double codedouble = (double)(codeInt - 1) * Math.pow((double)100.0F, (double)idx);
            BigDecimal bg = new BigDecimal(codedouble);
            if (idx < 0) {
               bg = bg.setScale(idx * 2 * -1, RoundingMode.HALF_DOWN);
            }

            reDouble = reDouble.add(bg);
            --idx;
         }

         reInt = DmpCommonTool.subZeroAndDot(String.valueOf(reDouble));
      } else if (ws < 0) {
         if (1 == intColLst.size() && "128".equals(((Integer)intColLst.get(0)).toString())) {
            reInt = "0";
         } else if (1 == intColLst.size() && "30".equals(((Integer)intColLst.get(0)).toString())) {
            reInt = "";
         } else {
            int idx = 62 - (Integer)intColLst.get(0);
            intColLst.remove(intColLst.size() - 1);
            intColLst.remove(0);

            while(intColLst.size() < idx + 1) {
               intColLst.add(101);
            }

            BigDecimal reDouble = new BigDecimal(0);

            for(int i = 0; i < intColLst.size(); ++i) {
               int codeInt = (Integer)intColLst.get(i);
               double codedouble = (double)(codeInt - 101) * Math.pow((double)100.0F, (double)idx);
               BigDecimal bg = new BigDecimal(codedouble);
               if (idx < 0) {
                  bg = bg.setScale(idx * 2 * -1, RoundingMode.HALF_DOWN);
               }

               reDouble = reDouble.add(bg);
               --idx;
            }

            reInt = DmpCommonTool.subZeroAndDot(String.valueOf(reDouble));
         }
      }

      return reInt;
   }

   private static String lNumberParsing(List<Integer> intColLst) {
      String reInt = "";
      int prefixNum = (Integer)intColLst.get(0);
      if (prefixNum == 45) {
         reInt = "-";

         for(int i = 1; i < intColLst.size(); ++i) {
            reInt = reInt + ((Integer)intColLst.get(i) - 48);
         }
      } else {
         for(int i = 0; i < intColLst.size(); ++i) {
            reInt = reInt + ((Integer)intColLst.get(i) - 48);
         }
      }

      return reInt;
   }

   private static List<String> createTableSql(List<String> dmpFilePathList) {
      Date startDate = new Date();
      List<String> createTableSqlList = new ArrayList();
      List<String> insertTableSql = new ArrayList();
      List<String> uniqueTableSql = new ArrayList();
      List<String> synonTableSql = new ArrayList();
      List<String> viewTableSql = new ArrayList();

      try {
         for(int i = 0; i < dmpFilePathList.size(); ++i) {
            String dmpFilePath = (String)dmpFilePathList.get(i);
            FileInputStream is = new FileInputStream(dmpFilePath);
            Reader reader = new InputStreamReader(is);
            BufferedReader bufferedReader = new BufferedReader(reader);
            String line = "";
            int lineNum = 0;

            while((line = bufferedReader.readLine()) != null) {
               ++lineNum;
               line = new String(line.getBytes("ISO-8859-1"), "GBK");
               if (line.length() > 12) {
                  String top12 = line.substring(0, 12);
                  if (top12.equals("CREATE TABLE")) {
                     createTableSqlList.add(line);
                  } else if (top12.equals("INSERT INTO ")) {
                     insertTableSql.add(line);
                  } else if (top12.equals("CREATE UNIQU")) {
                     uniqueTableSql.add(line);
                  } else if (top12.equals("CREATE SYNON")) {
                     synonTableSql.add(line);
                  } else if (top12.equals("CREATE VIEW ")) {
                     viewTableSql.add(line);
                  }
               }
            }
         }
      } catch (Exception e) {
         e.printStackTrace();
      }

      Date endDate = new Date();
      DateTime1Tool.dateBetween(startDate, endDate);
      return createTableSqlList;
   }

   private static String tableName2HexStr(String tablename) {
      byte[] tablenameByteArr = tablename.getBytes();
      StringBuffer tableNameHexBuf = new StringBuffer();

      for(int i = 0; i < tablenameByteArr.length; ++i) {
         byte tablenameByte = tablenameByteArr[i];
         String tablenameHexStr = DmpCommonTool.toHex(tablenameByte);
         tableNameHexBuf.append(tablenameHexStr);
      }

      return tableNameHexBuf.toString();
   }

   public static List<String> getAllTableNameList(List<String> dmpFilePathList) {
      List<String> createTableSqlList = createTableSql(dmpFilePathList);
      List<String> tableNameList = new ArrayList();

      for(int i = 0; i < createTableSqlList.size(); ++i) {
         String createTableSqlStr = (String)createTableSqlList.get(i);
         int tableNameStartIndex = createTableSqlStr.indexOf("TABLE") + 5;
         int tableNameEndIndex = createTableSqlStr.indexOf("(");
         String tableNameBuf = createTableSqlStr.substring(tableNameStartIndex, tableNameEndIndex);
         tableNameBuf = tableNameBuf.trim();
         String tName = tableNameBuf.replaceAll("\"", "");
         tableNameList.add(tName);
      }

      return tableNameList;
   }

   private static List<String> getTypeNameListByTableName(TableStructureInfo tableStructureInfo) {
      if (null == tableStructureInfo) {
         return null;
      } else {
         List<String> typeNameLst = new ArrayList();
         List<ColumnInfoVO> columnInfoList = tableStructureInfo.getColInfoLst();

         for(int j = 0; j < columnInfoList.size(); ++j) {
            typeNameLst.add(((ColumnInfoVO)columnInfoList.get(j)).getTypename());
         }

         return typeNameLst;
      }
   }

   public static List<ColumnInfoVO> getColListByTableName(List<String> dmpFilePathList, String tablename) {
      if (StringUtils.isBlank(tablename)) {
         return null;
      } else {
         List<ColumnInfoVO> columnInfoLst = new ArrayList();
         List<String> createTableSqlList = createTableSql(dmpFilePathList);

         for(int i = 0; i < createTableSqlList.size(); ++i) {
            String createTableSqlStr = (String)createTableSqlList.get(i);
            int tableNameStartIndex = createTableSqlStr.indexOf("TABLE") + 5;
            int tableNameEndIndex = createTableSqlStr.indexOf("(");
            String tableNameBuf = createTableSqlStr.substring(tableNameStartIndex, tableNameEndIndex);
            tableNameBuf = tableNameBuf.trim();
            String tName = tableNameBuf.replaceAll("\"", "");
            if (tablename.equalsIgnoreCase(tName)) {
               int colInfoStartIndex = createTableSqlStr.indexOf("(") + 1;
               int colInfoEndIndex = createTableSqlStr.indexOf(")  PCTFREE");
               String colInfosBuf = createTableSqlStr.substring(colInfoStartIndex, colInfoEndIndex);
               colInfosBuf = colInfosBuf.trim();
               String[] colInfoArr = colInfosBuf.split(", \"");

               for(int j = 0; j < colInfoArr.length; ++j) {
                  ColumnInfoVO columnInfo = new ColumnInfoVO();
                  String colInfoBuf = colInfoArr[j];
                  colInfoBuf = colInfoBuf.trim();
                  String[] colInfoBufArr = colInfoBuf.split("\" ");
                  String columnname = colInfoBufArr[0];
                  columnname = columnname.replaceAll("\"", "");
                  String colTypeBuf = colInfoBufArr[1];
                  String typename = colTypeBuf;
                  String columnsize = "";
                  String decimaldigits = null;
                  int colTypeEndIndex = colTypeBuf.indexOf("(");
                  if (colTypeEndIndex > 0) {
                     typename = colTypeBuf.substring(0, colTypeEndIndex);
                     int digitsEndIndex = colTypeBuf.indexOf(")");
                     String precisionStr = colTypeBuf.substring(colTypeEndIndex + 1, digitsEndIndex);
                     String[] precisionArr = precisionStr.split(",");
                     columnsize = precisionArr[0].trim();
                     if ("*".equalsIgnoreCase(columnsize) && "NUMBER".equalsIgnoreCase(typename)) {
                        columnsize = "38";
                     }

                     if (precisionArr.length > 1) {
                        decimaldigits = precisionArr[1].trim();
                     }
                  }

                  if ("date".equalsIgnoreCase(typename)) {
                     columnsize = "7";
                  }

                  columnInfo.setTablename(tablename);
                  columnInfo.setColumnname(columnname);
                  columnInfo.setTypename(typename);
                  columnInfo.setColumnsize(columnsize == null ? "" : columnsize);
                  columnInfo.setDecimaldigits(decimaldigits == null ? "" : decimaldigits);
                  columnInfo.setMaskingruleid("");
                  columnInfo.setMaskingrulename("");
                  columnInfo.setRegextype("");
                  columnInfo.setTargettypename("");
                  columnInfo.setRemarks("");
                  columnInfoLst.add(columnInfo);
               }
               break;
            }
         }

         return columnInfoLst;
      }
   }

   public static Map<String, Object> getAllTableinfo(List<String> dmpFilePathList) {
      Date startDate = new Date();
      String preTableName = "";
      List<TableStructureInfo> tableStructureInfoList = new ArrayList();
      Map<String, String> tableDataLineNumMap = new HashMap();
      Map<String, Object> reTableInfoMap = new HashMap();
      List<Integer> dmpFileTotalLineNumList = new ArrayList();
      int lineNum = 1;
      String isNewFile = "0";

      try {
         for(int i = 0; i < dmpFilePathList.size(); ++i) {
            isNewFile = "1";
            String dmpFilePath = (String)dmpFilePathList.get(i);
            FileReader fr = new FileReader(dmpFilePath);
            DmpBufferedReader reader = new DmpBufferedReader(fr);

            String line;
            for(line = ""; (line = reader.ReadLine()) != null; ++lineNum) {
               if (line.contains("IBMPC") && "1".equals(isNewFile)) {
                  return null;
               }

               isNewFile = "0";
               line = new String(line.getBytes("ISO-8859-1"), "GBK");
               if (line.length() <= 12) {
                  if (line.length() >= 4 && line.substring(0, 4).equals("EXIT")) {
                     tableDataLineNumMap.put(preTableName, (String)tableDataLineNumMap.get(preTableName) + "#_#" + dmpFilePath + "$_$" + lineNum);
                  }
               } else {
                  String top12 = line.substring(0, 12);
                  if (top12.equals("CREATE TABLE")) {
                     List<ColumnInfoVO> columnInfoLst = new ArrayList();
                     String createTableSqlStr = lineNum + line;
                     int tableNameStartIndex = createTableSqlStr.indexOf("TABLE") + 5;
                     int tableNameEndIndex = createTableSqlStr.indexOf("(");
                     String tableNameBuf = createTableSqlStr.substring(tableNameStartIndex, tableNameEndIndex);
                     tableNameBuf = tableNameBuf.trim();
                     String tName = tableNameBuf.replaceAll("\"", "");
                     int colInfoStartIndex = createTableSqlStr.indexOf("(") + 1;
                     int colInfoEndIndex = createTableSqlStr.indexOf(")  PCTFREE");
                     String colInfosBuf = createTableSqlStr.substring(colInfoStartIndex, colInfoEndIndex);
                     colInfosBuf = colInfosBuf.trim();
                     String[] colInfoArr = colInfosBuf.split(", \"");

                     for(int j = 0; j < colInfoArr.length; ++j) {
                        ColumnInfoVO columnInfo = new ColumnInfoVO();
                        String colInfoBuf = colInfoArr[j];
                        colInfoBuf = colInfoBuf.trim();
                        String[] colInfoBufArr = colInfoBuf.split("\" ");
                        String columnname = colInfoBufArr[0];
                        columnname = columnname.replaceAll("\"", "");
                        String colTypeBuf = colInfoBufArr[1];
                        String typename = colTypeBuf;
                        String columnsize = "";
                        String decimaldigits = null;
                        int colTypeEndIndex = colTypeBuf.indexOf("(");
                        if (colTypeEndIndex > 0) {
                           typename = colTypeBuf.substring(0, colTypeEndIndex);
                           int digitsEndIndex = colTypeBuf.indexOf(")");
                           String precisionStr = colTypeBuf.substring(colTypeEndIndex + 1, digitsEndIndex);
                           String[] precisionArr = precisionStr.split(",");
                           columnsize = precisionArr[0].trim();
                           if ("*".equalsIgnoreCase(columnsize) && "NUMBER".equalsIgnoreCase(typename)) {
                              columnsize = "38";
                           }

                           if (precisionArr.length > 1) {
                              decimaldigits = precisionArr[1].trim();
                           }
                        } else {
                           int notNullStartIndex = colTypeBuf.indexOf(" NOT");
                           if (notNullStartIndex > 0) {
                              typename = colTypeBuf.substring(0, notNullStartIndex);
                           }
                        }

                        if ("date".equalsIgnoreCase(typename)) {
                           columnsize = "7";
                        }

                        columnInfo.setTablename(tName);
                        columnInfo.setColumnname(columnname);
                        columnInfo.setTypename(typename);
                        columnInfo.setColumnsize(columnsize == null ? "" : columnsize);
                        columnInfo.setDecimaldigits(decimaldigits == null ? "" : decimaldigits);
                        columnInfo.setMaskingruleid("");
                        columnInfo.setMaskingrulename("");
                        columnInfo.setRegextype("");
                        columnInfo.setTargettypename("");
                        columnInfo.setRemarks("");
                        columnInfoLst.add(columnInfo);
                     }

                     if (StringUtils.isNotBlank(preTableName) && null != tableDataLineNumMap.get(preTableName) && ((String)tableDataLineNumMap.get(preTableName)).indexOf("#_#") < 0) {
                        tableDataLineNumMap.put(preTableName, (String)tableDataLineNumMap.get(preTableName) + "#_#" + dmpFilePath + "$_$" + lineNum);
                     }

                     if (!tableDataLineNumMap.containsKey(tName)) {
                        TableStructureInfo tableStructureInfo = new TableStructureInfo();
                        tableStructureInfo.setColInfoLst(columnInfoLst);
                        tableStructureInfo.setTablename(tName);
                        tableStructureInfoList.add(tableStructureInfo);
                     }

                     tableDataLineNumMap.put(tName, String.valueOf(dmpFilePath + "$_$" + lineNum));
                     preTableName = tName;
                  }
               }
            }

            dmpFileTotalLineNumList.add(lineNum - 1);
         }

         reTableInfoMap.put("tableStructureInfoList", tableStructureInfoList);
         reTableInfoMap.put("lineNumKey", tableDataLineNumMap);
         reTableInfoMap.put("dmpFileTotalLineNumList", dmpFileTotalLineNumList);
      } catch (Exception e) {
         e.printStackTrace();
      }

      Date endDate = new Date();
      DateTime1Tool.dateBetween(startDate, endDate);
      return reTableInfoMap;
   }

   public static void createPipeFile(String taskname, String tablename) {
      Properties props = new Properties();

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

      String path = props.getProperty("dmp_exp_table_file_path");
      String pipeFilePath = path + taskname + "/";
      FileTool.createFolder(pipeFilePath);
      String pipeFileName = tablename + ".pipe";
      String rmPipeFileCmd = "rm -rf " + pipeFilePath + pipeFileName;
      String mkrPipeFileCmd = "mkfifo " + pipeFilePath + pipeFileName;
      System.out.println(">>>>>>>>>>>mkrPipeFileCmd:" + mkrPipeFileCmd);
      CommandTool.command(rmPipeFileCmd);
      CommandTool.command(mkrPipeFileCmd);
      CommandTool.command("chmod -R 777 " + pipeFilePath + pipeFileName);
   }

   public static void prasingDataByTableName(List<String> dmpFilePathList, String taskname, String tablenamePar, Map<String, Object> tableInfoMap) {
      if (null != tableInfoMap && null != dmpFilePathList && dmpFilePathList.size() != 0) {
         Properties props = new Properties();

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

         Map<String, String> tableDataLineNumMap = (Map)tableInfoMap.get("lineNumKey");
         List<Integer> dmpFileTotalLineNumList = (List)tableInfoMap.get("dmpFileTotalLineNumList");
         List<TableStructureInfo> tableStructureInfoList = (List)tableInfoMap.get("tableStructureInfoList");

         for(int i = 0; i < tableStructureInfoList.size(); ++i) {
            String tablename = ((TableStructureInfo)tableStructureInfoList.get(i)).getTablename();
            if (tablenamePar.equals(tablename)) {
               try {
                  String path = props.getProperty("dmp_exp_table_file_path");
                  String pipeFilePath = path + taskname + "/";
                  String pipeFileName = tablename + ".pipe";
                  FileOutputStream os = new FileOutputStream(pipeFilePath + pipeFileName);
                  Writer writer = new OutputStreamWriter(os, "utf-8");
                  BufferedWriter bufferedWriter = new BufferedWriter(writer);
                  List<String> colTypeList = getTypeNameListByTableName((TableStructureInfo)tableStructureInfoList.get(i));
                  String LineNum = (String)tableDataLineNumMap.get(tablename);
                  String[] LineNums = LineNum.split("#_#");
                  String[] startLineArr = LineNums[0].split("\\$_\\$");
                  String[] endLineArr = LineNums[1].split("\\$_\\$");
                  int startLine = Integer.parseInt(startLineArr[1]);
                  int endLine = Integer.parseInt(endLineArr[1]);
                  byte[] btyebufArr = null;
                  int preEndLineReal = startLine;
                  String isFinishFlg = "0";
                  String nextDmpStartMark = "0";
                  int nextCnt = 0;
                  boolean issys = false;
                  String finishFlg = "0";
                  int colCnt = 0;
                  StringBuffer sb = new StringBuffer();
                  int count00 = 0;

                  for(int j = 0; j < dmpFileTotalLineNumList.size(); ++j) {
                     int nextDmpHeadIndex = 0;
                     Integer dmpCnt = (Integer)dmpFileTotalLineNumList.get(j);
                     if ("0".equals(isFinishFlg) && startLine < dmpCnt) {
                        if (dmpCnt < endLine) {
                           int endLineReal = dmpCnt;
                           btyebufArr = readDataByLineNum(dmpFilePathList, preEndLineReal, endLineReal);
                           preEndLineReal = endLineReal + 1;
                           ++nextCnt;
                        } else {
                           btyebufArr = readDataByLineNum(dmpFilePathList, preEndLineReal, endLine);
                           isFinishFlg = "1";
                           ++nextCnt;
                        }

                        if (nextCnt > 1) {
                           nextDmpStartMark = "1";
                        }

                        int btyebufArrIndex = 0;
                        String lastbuf16 = "";
                        String buf16Str6 = "";
                        String nextDmpStartMonitorData = "0";

                        while(btyebufArrIndex < btyebufArr.length) {
                           byte bufbyte = btyebufArr[btyebufArrIndex];
                           String buf10 = DmpCommonTool.toInt(bufbyte);
                           String buf16 = DmpCommonTool.toHex(bufbyte);
                           buf16Str6 = buf16Str6 + buf16;
                           if (buf16Str6.length() > 12) {
                              buf16Str6 = buf16Str6.substring(2);
                           }

                           if (!issys) {
                              if (count00 == 5) {
                                 if (!buf16.equals("00")) {
                                    issys = true;
                                 } else {
                                    count00 = -1;
                                 }
                              }

                              if (buf16.equals("00")) {
                                 ++count00;
                              } else {
                                 count00 = 0;
                              }
                           }

                           if (issys) {
                              if ("1".equals(nextDmpStartMark)) {
                                 if ("2E646D700000".equals(buf16Str6) && "0".equals(nextDmpStartMonitorData)) {
                                    nextDmpStartMonitorData = "1";
                                 }

                                 if ("1".equals(nextDmpStartMonitorData) && !buf16.equals("00") && lastbuf16.equals("00")) {
                                    nextDmpStartMark = "0";
                                    int Remainder = btyebufArrIndex % 16;

                                    for(int k = 0; k < Remainder; ++k) {
                                       sb.append(0).append(",");
                                       --colCnt;
                                    }
                                 }
                              }

                              if ("0".equals(nextDmpStartMark)) {
                                 if (buf16.equals("00") && lastbuf16.equals("00") && colCnt == 0) {
                                    String sbInt = sb.toString().substring(0, sb.length() - 3);
                                    StringBuffer writebuf = parsingDataByLine(colTypeList, sbInt, ",", "1");
                                    bufferedWriter.write(writebuf.toString());
                                    sb = new StringBuffer();
                                 } else if (buf16.equals("FF") && lastbuf16.equals("FF")) {
                                    finishFlg = "1";
                                 } else {
                                    if (colCnt == 0) {
                                       if ("FE".equals(buf16)) {
                                          colCnt = 0;
                                       } else if ("FE".equals(lastbuf16)) {
                                          if ("FF".equals(buf16)) {
                                             colCnt = 0;
                                          } else if ("00".equals(buf16)) {
                                             colCnt = Integer.valueOf(lastbuf16, 16);
                                          } else {
                                             colCnt = Integer.valueOf(buf10) + 1;
                                          }
                                       } else if (!"0".equals(buf10)) {
                                          colCnt = Integer.valueOf(buf10) + 1;
                                       }
                                    } else {
                                       --colCnt;
                                    }

                                    sb.append(buf10).append(",");
                                 }
                              }
                           }

                           lastbuf16 = buf16;
                           ++btyebufArrIndex;
                           if ("1".equals(finishFlg)) {
                              bufferedWriter.flush();
                              bufferedWriter.close();
                              break;
                           }
                        }
                     }
                  }
               } catch (Exception e) {
                  e.printStackTrace();
               }
            }
         }

      }
   }

   public static Map<String, List<List<Object>>> prasingDataByTableNameByRowNum(List<String> dmpFilePathList, Map<String, Object> tableInfoMap, List<String> selectTableList, Long parMaxCnt) {
      if (null != tableInfoMap && null != dmpFilePathList && dmpFilePathList.size() != 0 && tableInfoMap.size() != 0) {
         Map<String, List<List<Object>>> reDataLstMap = new HashMap();
         new ArrayList();
         new Properties();

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

         Map<String, String> selectTableMap = new HashMap();

         for(int i = 0; i < selectTableList.size(); ++i) {
            selectTableMap.put(selectTableList.get(i), "");
         }

         List<TableStructureInfo> tableStructureInfoList = (List)tableInfoMap.get("tableStructureInfoList");
         Map<String, String> tableDataLineNumMap = (Map)tableInfoMap.get("lineNumKey");
         List<Integer> dmpFileTotalLineNumList = (List)tableInfoMap.get("dmpFileTotalLineNumList");

         for(int i = 0; i < tableStructureInfoList.size(); ++i) {
            List<List<Object>> reDataLst = new ArrayList();
            String tablename = ((TableStructureInfo)tableStructureInfoList.get(i)).getTablename();
            if (selectTableMap.containsKey(tablename)) {
               Long maxCnt = parMaxCnt;
               List<String> colTypeList = getTypeNameListByTableName((TableStructureInfo)tableStructureInfoList.get(i));
               String LineNum = (String)tableDataLineNumMap.get(tablename);
               String[] LineNums = LineNum.split("#_#");
               String[] startLineArr = LineNums[0].split("\\$_\\$");
               String[] endLineArr = LineNums[1].split("\\$_\\$");
               int startLine = Integer.parseInt(startLineArr[1]);
               int endLine = Integer.parseInt(endLineArr[1]);
               byte[] btyebufArr = null;
               int preEndLineReal = startLine;
               String isCurTableDataLastFinishFlg = "0";
               String nextDmpStartMark = "0";
               int nextCnt = 0;
               boolean issys = false;
               int count00 = 0;
               String finishFlg = "0";
               StringBuffer sb = new StringBuffer();
               int colCnt = 0;

               for(int j = 0; j < dmpFileTotalLineNumList.size() && !"1".equals(isCurTableDataLastFinishFlg) && !"1".equals(finishFlg); ++j) {
                  int nextDmpHeadIndex = 0;
                  Integer dmpCnt = (Integer)dmpFileTotalLineNumList.get(j);
                  if (startLine < dmpCnt) {
                     int endLineReal;
                     if (dmpCnt < endLine) {
                        endLineReal = dmpCnt;
                     } else {
                        endLineReal = endLine;
                        isCurTableDataLastFinishFlg = "1";
                     }

                     int execCnt = (endLineReal - preEndLineReal + 1) / 5000;
                     int lastTimeLineNum = 0;
                     if (execCnt <= 0) {
                        btyebufArr = readDataByLineNum(dmpFilePathList, preEndLineReal, endLineReal);
                     } else {
                        btyebufArr = readDataByLineNum(dmpFilePathList, preEndLineReal, preEndLineReal + 5000);
                        lastTimeLineNum = (endLine - startLine) % 5000;
                     }

                     if (nextCnt >= 1) {
                        nextDmpStartMark = "1";
                     }

                     ++nextCnt;
                     int btyebufArrIndex = 0;
                     String lastbuf16 = "";
                     String buf16Str6 = "";
                     String nextDmpStartMonitorData = "0";
                     int hasExecCnt = 1;
                     boolean lastFlg = false;

                     while(btyebufArrIndex <= btyebufArr.length) {
                        if (btyebufArrIndex == btyebufArr.length) {
                           if (lastFlg) {
                              break;
                           }

                           if (hasExecCnt < execCnt) {
                              btyebufArr = readDataByLineNum(dmpFilePathList, preEndLineReal + 5000 * hasExecCnt + 1, preEndLineReal + 5000 * (hasExecCnt + 1));
                              btyebufArrIndex = 0;
                           } else if (lastTimeLineNum != 0) {
                              btyebufArr = readDataByLineNum(dmpFilePathList, preEndLineReal + 5000 * hasExecCnt + 1, endLineReal);
                              btyebufArrIndex = 0;
                              lastFlg = true;
                           }

                           ++hasExecCnt;
                        }

                        byte bufbyte = btyebufArr[btyebufArrIndex];
                        String buf10 = DmpCommonTool.toInt(bufbyte);
                        String buf16 = DmpCommonTool.toHex(bufbyte);
                        buf16Str6 = buf16Str6 + buf16;
                        if (buf16Str6.length() > 12) {
                           buf16Str6 = buf16Str6.substring(2);
                        }

                        if (!issys) {
                           if (count00 == 5) {
                              if (!buf16.equals("00")) {
                                 issys = true;
                              } else {
                                 count00 = -1;
                              }
                           }

                           if (buf16.equals("00")) {
                              ++count00;
                           } else {
                              count00 = 0;
                           }
                        }

                        if (issys) {
                           if ("1".equals(nextDmpStartMark)) {
                              if ("2E646D700000".equals(buf16Str6) && "0".equals(nextDmpStartMonitorData)) {
                                 nextDmpStartMonitorData = "1";
                              }

                              if ("1".equals(nextDmpStartMonitorData) && !buf16.equals("00") && lastbuf16.equals("00")) {
                                 nextDmpStartMark = "0";
                                 int Remainder = btyebufArrIndex % 16;

                                 for(int k = 0; k < Remainder; ++k) {
                                    sb.append(0).append(",");
                                    --colCnt;
                                 }
                              }
                           }

                           if ("0".equals(nextDmpStartMark)) {
                              if (buf16.equals("00") && lastbuf16.equals("00") && colCnt == 0) {
                                 String sbInt = sb.toString().substring(0, sb.length() - 3);
                                 StringBuffer writebuf = parsingDataByLine(colTypeList, sbInt, ",", "");
                                 if (maxCnt <= 0L) {
                                    finishFlg = "1";
                                 }

                                 if (null != writebuf && writebuf.length() > 0 && !"1".equals(finishFlg)) {
                                    String writebufStr = writebuf.toString();
                                    String[] writebufStrArr = writebufStr.split(STR_DATA_SEPARATOR);
                                    List<Object> list = Arrays.asList(writebufStrArr);
                                    List<Object> arrList = new ArrayList(list);
                                    arrList.remove(arrList.size() - 1);
                                    reDataLst.add(arrList);
                                 }

                                 maxCnt = maxCnt - 1L;
                                 sb = new StringBuffer();
                              } else if (buf16.equals("FF") && lastbuf16.equals("FF")) {
                                 finishFlg = "1";
                              } else {
                                 if (colCnt == 0) {
                                    if ("FE".equals(buf16)) {
                                       colCnt = 0;
                                    } else if ("FE".equals(lastbuf16)) {
                                       if ("FF".equals(buf16)) {
                                          colCnt = 0;
                                       } else if ("00".equals(buf16)) {
                                          colCnt = Integer.valueOf(lastbuf16, 16);
                                       } else {
                                          colCnt = Integer.valueOf(buf10) + 1;
                                       }
                                    } else if (!"0".equals(buf10)) {
                                       colCnt = Integer.valueOf(buf10) + 1;
                                    }
                                 } else {
                                    --colCnt;
                                 }

                                 sb.append(buf10).append(",");
                              }
                           }
                        }

                        lastbuf16 = buf16;
                        ++btyebufArrIndex;
                        if ("1".equals(finishFlg)) {
                           break;
                        }
                     }

                     if (dmpCnt < endLine) {
                        preEndLineReal = endLineReal + 1;
                     }
                  }
               }

               reDataLstMap.put(tablename, reDataLst);
            }
         }

         return reDataLstMap;
      } else {
         return null;
      }
   }

   public static byte[] readDataByLineNum(List<String> dmpPathList, int startLine, int endLine) {
      String pathStr = "";

      for(int i = 0; i < dmpPathList.size(); ++i) {
         pathStr = pathStr + (String)dmpPathList.get(i) + " ";
      }

      pathStr = pathStr.substring(0, pathStr.length() - 1);
      String cmdStr = "sed -n '" + startLine + "," + endLine + "p' " + pathStr;
      byte[] reBtyebufArr = remoteRunCmd(cmdStr);
      return reBtyebufArr;
   }

   public static byte[] remoteRunCmd(String cmd) {
      String hostname = "127.0.0.1";
      String username = "infa";
      String password = "infa";
      byte[] btyebufArr = new byte[10000];
      Connection conn = new Connection(hostname);
      byte[] in_b = null;
      Session sess = null;

      try {
         conn.connect();
         boolean isAuthenticated = conn.authenticateWithPassword(username, password);
         if (!isAuthenticated) {
            throw new IOException("Authentication failed.");
         }

         sess = conn.openSession();
         sess.execCommand(cmd);
         InputStream in = sess.getStdout();
         int num = 0;
         ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
         int rc = 0;

         while((rc = in.read(btyebufArr, 0, 10000)) > 0) {
            swapStream.write(btyebufArr, 0, rc);
         }

         in_b = swapStream.toByteArray();
      } catch (IOException e) {
         e.printStackTrace(System.err);
         System.exit(2);
      } finally {
         sess.close();
         conn.close();
      }

      return in_b;
   }

   public static List<List<Object>> prasingNotConfirmDataByTableNameByRowNum(List<String> dmpFilePathList, String tablename, Long maxCnt, List<String> notConfirmColLst, Map<String, Object> tableInfoMap) {
      if (null != tablename && null != notConfirmColLst && 0 != notConfirmColLst.size()) {
         Map<String, String> notConfirmMap = new HashMap();

         for(int i = 0; i < notConfirmColLst.size(); ++i) {
            String notConfirmColName = (String)notConfirmColLst.get(i);
            notConfirmMap.put(notConfirmColName, "");
         }

         List<String> selectTableList = new ArrayList();
         selectTableList.add(tablename);
         Map<String, List<List<Object>>> reDataMap = prasingDataByTableNameByRowNum(dmpFilePathList, tableInfoMap, selectTableList, maxCnt);
         List<List<Object>> reDataLst = (List)reDataMap.get(tablename);
         List<TableStructureInfo> tableStructureInfoList = (List)tableInfoMap.get("tableStructureInfoList");
         Map<String, TableStructureInfo> tableStructureInfoMap = new HashMap();

         for(int i = 0; i < tableStructureInfoList.size(); ++i) {
            tableStructureInfoMap.put(((TableStructureInfo)tableStructureInfoList.get(i)).getTablename(), tableStructureInfoList.get(i));
         }

         List<ColumnInfoVO> colInfoList = ((TableStructureInfo)tableStructureInfoMap.get(tablename)).getColInfoLst();

         for(int i = 0; i < reDataLst.size(); ++i) {
            List<Object> objLst = (List)reDataLst.get(i);

            for(int j = objLst.size() - 1; j >= 0; --j) {
               String columnname = ((ColumnInfoVO)colInfoList.get(j)).getColumnname();
               if (!notConfirmMap.containsKey(columnname)) {
                  objLst.remove(j);
               }
            }
         }

         return reDataLst;
      } else {
         return null;
      }
   }

   public static void main(String[] args) {
      new DmpTool();
      Properties props = new Properties();

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

      String dmppath = props.getProperty("dmp_file_path");
      long starttime = (new Date()).getTime();
      String tablename = "IP_INVPTY103";
      tablename = tablename.toUpperCase();
      dmppath = "D:/work/Masking_Engine/dmp/DMP解析数据类型调研/";
      List<String> dmpFilePathList = new ArrayList();
      List<String> locdmpFilePathList = new ArrayList();

      for(int i = 0; i < 2; ++i) {
         String numStr = String.format("%02d", i + 1);
         String dmpFilePath = "test" + numStr + ".dmp";
         dmpFilePathList.add(dmppath + dmpFilePath);
         locdmpFilePathList.add("D:/work/Masking_Engine/dmp/DMP解析数据类型调研/" + dmpFilePath);
      }

      Map<String, Object> tableInfoMap = getAllTableinfo(dmpFilePathList);
      List<String> selectTableList = new ArrayList();
      selectTableList.add("DMP_TEST");
      selectTableList.add("DMP_TEST1");
      selectTableList.add("IP_INVPTY");
      selectTableList.add("IP_INVPTY102");
      selectTableList.add("IP_INVPTY103");
      prasingDataByTableName(locdmpFilePathList, "191016140654_dmp2dmptest3", "IP_INVPTY104", tableInfoMap);
      long endtime = (new Date()).getTime();
      System.out.println("总耗时:" + (endtime - starttime) + "毫秒");
   }

   public static String dmpNum(String num) {
      int len = num.length();
      if (len % 2 != 0) {
         num = "0" + num;
      }

      char[] numChrArr = num.toCharArray();
      String reCode = "";
      String codeBuf = "";

      for(int i = numChrArr.length - 1; i >= 0; i -= 2) {
         String buf = numChrArr[i - 1] + String.valueOf(numChrArr[i]);
         int bufInt = Integer.valueOf(buf);
         ++bufInt;
         codeBuf = String.format("%02x", bufInt);
         reCode = codeBuf + reCode;
      }

      String preHexCode = DmpCommonTool.intToHex((numChrArr.length - 2) / 2 + 193);
      reCode = preHexCode + reCode;
      System.out.println("数字：" + num + "通过dmp转为code：  " + reCode);
      return reCode;
   }
}
