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

import com.chenyang.nse.bussiness.config.PropertiesLoaderUtils;
import com.chenyang.nse.bussiness.enumeration.EdbType;
import com.chenyang.nse.bussiness.tools.datatime.DateTimeTool;
import com.chenyang.nse.bussiness.tools.string.StringTool;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.apache.commons.lang.StringUtils;

public class PipeTool {
   private Connection con;
   private String tableName;
   private String filePath;
   private String delimiter;
   private String charset;
   private String sqlFilter;
   private Thread t;
   private String quoteCharacter;

   public PipeTool(Connection con, String tableName, String filePath, String delimiter, String charset) {
      this.con = con;
      this.tableName = tableName;
      this.filePath = filePath;
      this.delimiter = delimiter;
      this.charset = charset;
   }

   public PipeTool() {
   }

   public PipeTool(Connection con, String tableName, String filePath, String delimiter, String charset, String sqlFilter) {
      this.con = con;
      this.tableName = tableName;
      this.filePath = filePath;
      this.delimiter = delimiter;
      this.charset = charset;
      this.sqlFilter = sqlFilter;
   }

   public PipeTool(Connection con, String tableName, String filePath, String delimiter, String charset, String sqlFilter, String quoteCharacter) {
      this.con = con;
      this.tableName = tableName;
      this.filePath = filePath;
      this.delimiter = delimiter;
      this.charset = charset;
      this.sqlFilter = sqlFilter;
      this.quoteCharacter = quoteCharacter;
   }

   public void writeFile() {
      String driverName = EdbType.HIVE.getDbdriver();
      PreparedStatement ps = null;
      ResultSet rs = null;
      FileOutputStream fos = null;
      OutputStreamWriter osw = null;
      BufferedWriter bw = null;
      Properties props = new Properties();

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

      String limit = props.getProperty("selectlimit");
      File file = new File(this.filePath);
      String sql = "select * from " + this.tableName;
      if (this.sqlFilter != null && !this.sqlFilter.equals("")) {
         sql = sql + " where " + this.sqlFilter;
      } else {
         sql = sql + " " + limit;
      }

      System.out.println(sql);

      try {
         Class.forName(driverName);
         ps = this.con.prepareStatement(sql, 1003, 1007);
         ps.setFetchSize(20000);
         rs = ps.executeQuery();
         fos = new FileOutputStream(file);
         osw = new OutputStreamWriter(fos, this.charset);
         bw = new BufferedWriter(osw);
         int columnSize = rs.getMetaData().getColumnCount();
         StringBuffer sb = new StringBuffer();
         System.out.println(">>>>>>>>>>>>>>>>>>>>HIVE JDBC读取，分隔符为" + this.delimiter);

         while(rs.next()) {
            for(int i = 1; i < columnSize; ++i) {
               String columnValue = String.valueOf(rs.getObject(i)).replace(this.delimiter, "");
               sb.append(columnValue);
               sb.append(this.delimiter);
            }

            sb.append(rs.getObject(columnSize));
            sb.append("\n");
            bw.write(sb.toString());
            bw.flush();
            sb.setLength(0);
         }
      } catch (SQLException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      } catch (ClassNotFoundException e) {
         e.printStackTrace();
      } finally {
         if (bw != null) {
            try {
               bw.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
         }

         if (osw != null) {
            try {
               osw.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
         }

         if (fos != null) {
            try {
               fos.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
         }

         if (rs != null) {
            try {
               rs.close();
            } catch (SQLException e) {
               e.printStackTrace();
            }
         }

         if (ps != null) {
            try {
               ps.close();
            } catch (SQLException e) {
               e.printStackTrace();
            }
         }

         if (this.con != null) {
            try {
               this.con.close();
            } catch (SQLException e) {
               e.printStackTrace();
            }
         }

      }

   }

   public int insertDataByPipeData11(String dataStr) {
      int reFlg = 0;
      if (StringUtils.isNotBlank(dataStr)) {
         String[] lineArr = dataStr.split("#_newline_#");
         String excSql = "INSERT INTO " + this.tableName + " VALUES ";
         StringBuffer insertLinesColBuffer = new StringBuffer();

         for(int i = 0; i < lineArr.length; ++i) {
            if (StringUtils.isNotBlank(lineArr[i])) {
               String[] dataArr = lineArr[i].split("#_COL_#");
               StringBuffer lineColBuffer = new StringBuffer();

               for(int j = 0; j < dataArr.length; ++j) {
                  lineColBuffer.append(dataArr[j] + ",");
               }

               String lineColStr = lineColBuffer.substring(0, lineColBuffer.length() - 1);
               insertLinesColBuffer.append("(" + lineColStr + ")");
               if (i < lineArr.length - 1) {
                  insertLinesColBuffer.append(",");
               } else {
                  insertLinesColBuffer.append(";");
               }
            }
         }

         excSql = excSql + insertLinesColBuffer.toString();
         PreparedStatement statement = null;

         try {
            statement = this.con.prepareStatement(excSql);
            reFlg = statement.executeUpdate();
            this.con.commit();
         } catch (SQLException e) {
            System.out.println(">>>>>>>>>>>>>>>>>>>>erro excSql:" + excSql);
            e.printStackTrace();
         }
      }

      return reFlg;
   }

   public int insertDataByPipeData(String dataStr) {
      int reFlg = 0;
      if (StringUtils.isNotBlank(dataStr)) {
         String[] lineArr = dataStr.split("#_newline_#");
         String excSql = "";
         StringBuffer insertLinesColBuffer = new StringBuffer();

         for(int i = 0; i < lineArr.length; ++i) {
            if (StringUtils.isNotBlank(lineArr[i])) {
               String[] dataArr = lineArr[i].split("#_COL_#");
               StringBuffer lineColBuffer = new StringBuffer();

               for(int j = 0; j < dataArr.length; ++j) {
                  lineColBuffer.append(dataArr[j] + ",");
               }

               String lineColStr = lineColBuffer.substring(0, lineColBuffer.length() - 1);
               insertLinesColBuffer.append("INSERT INTO " + this.tableName + " VALUES (" + lineColStr + "); ");
            }
         }

         excSql = insertLinesColBuffer.toString();
         PreparedStatement statement = null;

         try {
            statement = this.con.prepareStatement(excSql);
            reFlg = statement.executeUpdate();
            this.con.commit();
         } catch (SQLException e) {
            System.out.println(">>>>>>>>>>>>>>>>>>>>erro excSql:" + excSql);
            e.printStackTrace();
         }
      }

      return reFlg;
   }

   public String pipeFileRead() {
      System.out.println(">>>>>>>>pipeFileRead start: filepah:" + this.filePath);
      File file = new File(this.filePath);
      String str = "";
      StringBuilder sb = new StringBuilder();
      int minInsertLineNum = 5000;

      try {
         BufferedReader bReader = new BufferedReader(new InputStreamReader(new FileInputStream(file), this.charset));
         String s = "";
         int line = 0;
         System.out.println(">>>>>>>>pipeFileRead :pipe insert data start" + DateTimeTool.getSysTime(""));

         while((s = bReader.readLine()) != null) {
            if (line == 0) {
               System.out.println(">>>>>>>>pipeFileRead :first insert data start" + DateTimeTool.getSysTime(""));
            }

            sb.append(s + "#_newline_#");
            ++line;
            if (line % minInsertLineNum == 0) {
               this.insertDataByPipeData(sb.toString());
               sb = new StringBuilder();
            }
         }

         this.insertDataByPipeData(sb.toString());
         bReader.close();
         System.out.println("read file over :all line: " + line);
      } catch (Exception e) {
         System.out.println(e.toString());
      }

      System.out.println(">>>>>>>>pipeFileRead end: filepah:" + this.filePath);
      return str;
   }

   public void insert_into_hive() {
      Properties props = new Properties();

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

      String limit = props.getProperty("insertlimit");
      long abc = System.currentTimeMillis();
      FileInputStream inputStream = null;
      new StringBuffer();
      StringBuffer sb_colum = new StringBuffer();
      Reader in = null;
      BufferedReader reader = null;
      String path = this.filePath;
      String code = this.charset;
      String delimiter = this.delimiter;
      System.out.println("charset:" + this.charset);
      System.out.println("delimiter：" + delimiter);
      System.out.println("quoteCharacter：" + this.quoteCharacter);
      String quoteCharacter = this.quoteCharacter;
      String driverName = EdbType.HIVE.getDbdriver();
      Statement ps = null;
      StringBuffer ac = new StringBuffer();

      for(int j = 0; j < delimiter.length(); ++j) {
         if (!StringTool.isLetterDigitOrChinese(delimiter.substring(j, j + 1))) {
            ac.append("\\");
         }

         ac.append(delimiter.substring(j, j + 1));
      }

      new ArrayList();

      try {
         in = new InputStreamReader(new FileInputStream(path), code);
         reader = new BufferedReader(in);
         String line = null;
         Class.forName(driverName);
         sb_colum.append("insert into table " + this.tableName + " values ");
         long num = 0L;
         System.out.println("charset:" + this.charset);
         System.out.println("ac：" + ac.toString());
         System.out.println("delimiter：" + delimiter);
         System.out.println("quoteCharacter：" + quoteCharacter);

         while((line = reader.readLine()) != null) {
            ++num;
            String[] coulmn = line.split(ac.toString());
            if (coulmn.length > 0 && !line.equals("")) {
               label405: {
                  int i;
                  switch (quoteCharacter) {
                     case "0":
                        sb_colum.append("(");

                        for(int inew1 = 0; inew1 < coulmn.length; ++inew1) {
                           sb_colum.append("'");
                           sb_colum.append(coulmn[inew1]);
                           sb_colum.append("'");
                           sb_colum.append(",");
                        }

                        sb_colum.deleteCharAt(sb_colum.length() - 1);
                        sb_colum.append("),");
                        break label405;
                     default:
                        sb_colum.append("(");
                        i = 0;
                  }

                  while(i < coulmn.length) {
                     sb_colum.append(coulmn[i]);
                     if (coulmn[i].equals("")) {
                        if (quoteCharacter.equals("2")) {
                           sb_colum.append("\"\"");
                        } else if (quoteCharacter.equals("1")) {
                           sb_colum.append("''");
                        }
                     }

                     sb_colum.append(",");
                     ++i;
                  }

                  sb_colum.deleteCharAt(sb_colum.length() - 1);
                  sb_colum.append("),");
               }
            }

            if (!"0".equals(limit) && num % (long)Integer.parseInt(limit) == 0L) {
               sb_colum.deleteCharAt(sb_colum.length() - 1);
               ps = this.con.createStatement();
               ps.execute(sb_colum.toString());
               num = 0L;
               sb_colum.setLength(0);
               sb_colum.append("insert into table " + this.tableName + " values ");
               System.out.println("提交");
            }
         }

         if (num != 0L) {
            sb_colum.deleteCharAt(sb_colum.length() - 1);
            ps = this.con.createStatement();
            ps.execute(sb_colum.toString());
            System.out.println("提交");
         }

         in.close();
         reader.close();
      } catch (FileNotFoundException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      } catch (ClassNotFoundException e) {
         e.printStackTrace();
      } catch (SQLException e) {
         e.printStackTrace();
      } finally {
         if (ps != null) {
            try {
               ps.close();
            } catch (SQLException e) {
               e.printStackTrace();
            }
         }

         if (this.con != null) {
            try {
               this.con.close();
            } catch (SQLException e) {
               e.printStackTrace();
            }
         }

         if (inputStream != null) {
            try {
               inputStream.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
         }

      }

   }

   public void selectDataList(List<String> sql) throws Exception {
      PreparedStatement ps = null;

      for(String str : sql) {
         ps = this.con.prepareStatement(str);
         ps.execute();
      }

      ps.close();
      this.con.close();
   }

   public static void main(String[] args) {
      PipeTool p = new PipeTool();
      p.insert_into_hive();
   }
}
