package org.ts.ddcs.Worker;


import org.ts.ddcs.Log.LogHelper;
import org.ts.ddcs.Tool.BytesHelp;


import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.LinkedList;
import java.util.concurrent.Callable;

@SuppressWarnings("all")
public class RtuWorker implements Callable<Integer> {
    private String rtuCode;

    public RtuWorker(String rtuCode) {
        this.rtuCode = rtuCode;
    }

    @Override
    public Integer call() {
        try {
            LogHelper.info("rtu start:"+rtuCode);

            Socket socket = new Socket("120.224.44.183", 48001);
            // 建立连接后获得输出流

            int serialNo=1;
            OutputStream outputStream = socket.getOutputStream();
            InputStream input = socket.getInputStream();
            int min5 =0;

            int min = 0;
            boolean issend2f=true;
            while (true){
               try {

                   if(socket==null){
                       socket = new Socket("120.224.44.183", 48001);
                       // 建立连接后获得输出流
                       outputStream = socket.getOutputStream();
                       input = socket.getInputStream();
                   }

                   Date dt = new Date();
                   GregorianCalendar gc = new GregorianCalendar();
                   gc.setTime(dt);
                   int nowmin = gc.get(GregorianCalendar.MINUTE);
                   int nowmin5 = nowmin > 0 ? (nowmin / (int) 5) * 5 : 0;
                   if (nowmin5 != min5) {
                       LinkedList<String> rtu = new LinkedList<>();
                       double basevalue = 14.19;
                       double r = Math.random() * 0.1;
                       basevalue += r;
                       int value = (int) (basevalue * 100);
                       rtu.addLast("0082828800:3B23000" + Integer.toString(value) + "045200000048138121199");

                       for (String rtucode : rtu) {
                           try {
                               SimpleDateFormat timeFormat = new SimpleDateFormat("yyyyMMddHHmmss");
                               String tsStr = timeFormat.format(new Date());

                               String[] codes = rtucode.split(":");
                               String head = "7E7E";
                               head += "01";
                               head += codes[0];
                               head += "0000";
                               head += "32";
                               head += "0027";

                               String content = "";
                               content += "02";
                               byte[] s = BytesHelp.int2Bytes(serialNo, 2);
                               content += BytesHelp.byte2HexStr(s);
                               content += tsStr.substring(2);
                               content += "F1F1";
                               content += codes[0];

                               content += "50";

                               content += "F0F0";
                               String collectTime = tsStr.substring(2, tsStr.length() - 4);
                               collectTime += "00";
                               content += collectTime;
                               content += codes[1];
                               content += "03";

                               byte[] headbuff = BytesHelp.hexStr2Bytes(head);
                               byte[] contentbuff = BytesHelp.hexStr2Bytes(content);

                               byte[] respPacket = BytesHelp.arrayApend(headbuff, contentbuff);//CRC16
                               byte[] crc16 = BytesHelp.crcFun2014(respPacket);
                               respPacket = BytesHelp.arrayApend(respPacket, crc16);


                           } catch (Exception e) {
                               e.printStackTrace();
                           }
                       }

                       serialNo += 1;
                       min5 = nowmin5;
                       min = nowmin5;
                   } else {
                       if (nowmin != min && issend2f) {

                           SimpleDateFormat timeFormat = new SimpleDateFormat("yyyyMMddHHmmss");
                           String tsStr = timeFormat.format(new Date());

                           String head = "7E7E";
                           head += "01";
                           head += rtuCode;
                           head += "0000";
                           head += "2F";
                           head += "0008";

                           String content = "";
                           content += "02";
                           byte[] s = BytesHelp.int2Bytes(serialNo, 2);

                           content += BytesHelp.byte2HexStr(s);
                           content += tsStr.substring(2);

                           content += "03";

                           byte[] headbuff = BytesHelp.hexStr2Bytes(head);
                           byte[] contentbuff = BytesHelp.hexStr2Bytes(content);

                           byte[] respPacket = BytesHelp.arrayApend(headbuff, contentbuff);//CRC16
                           byte[] crc16 = BytesHelp.crcFun2014(respPacket);
                           respPacket = BytesHelp.arrayApend(respPacket, crc16);

                           LogHelper.info("************* rtu send datagram 2f " + BytesHelp.byte2HexStr(respPacket));

                           outputStream.write(respPacket);

                           serialNo += 1;
                           min = nowmin;

                           issend2f=true;
                       }
                   }


                   byte[] tmpbuff = new byte[2048];
                   byte[] bytes = new byte[1];
                   int len;
                   int count = 0;
                   StringBuilder sb = new StringBuilder();
                   int timeout = 0;



                   int packlen=0;

                   int step=0;

                   while (true) {

                       int read = input.available();
                       if (read <= 0) {
                           if (timeout > 1000) {
                               break;
                          }
                           Thread.sleep(100);
                           timeout += 100;
                       } else {
                           len = input.read(bytes, 0, 1);

                           if (len != -1) {
                               System.arraycopy(bytes, 0, tmpbuff, count, len);
                               count += len;
                              if(step==0){
                                  if(count ==13){



                                      byte[] dataAreaLen = new byte[2];
                                      dataAreaLen[0] = tmpbuff[11];
                                      dataAreaLen[1] = tmpbuff[12];

                                      String dflag  = BytesHelp.byte2HexStr(dataAreaLen);
                                      dflag = "0"+ dflag.substring(1,dflag.length());

                                      byte[] lenbuff = BytesHelp.hexStr2Bytes(dflag);


                                      int contensize = BytesHelp.bytes2Int(lenbuff,0,2);// 报文长度(int)
                                      packlen  = 11 + contensize + 6;

                                     step=1;
                                  }
                              }else{

                                  if(count == packlen){
                                      break;
                                  }

                              }

                           } else {
                               break;
                           }
                       }


                   }



                   if (count > 0) {

                       byte[] responsebuff = new byte[count];
                       System.arraycopy(tmpbuff, 0, responsebuff, 0, count);
                       byte[] PacketCrc16 = new byte[2];
                       PacketCrc16[0] = responsebuff[responsebuff.length - 2];
                       PacketCrc16[1] = responsebuff[responsebuff.length - 1];
                       LogHelper.info("************* rtu get response " + BytesHelp.byte2HexStr(responsebuff));
                       byte[] crc16 = BytesHelp.crcFun2014(responsebuff, 0, responsebuff.length - 2);
                       if (!BytesHelp.byte2HexStr(PacketCrc16).equals(BytesHelp.byte2HexStr(crc16))) {
                           LogHelper.info("校验码错误：报文中 CRC=" + BytesHelp.byte2HexStr(PacketCrc16) + " 计算的 CRC=" + BytesHelp.byte2HexStr(crc16));
                       }else{

                           if(responsebuff[10] == (byte) 0xF1){

                               issend2f=false;

                               SimpleDateFormat timeFormat = new SimpleDateFormat("yyyyMMddHHmmss");
                               String tsStr = timeFormat.format(new Date());


                               String head = "7E7E";
                               head += "01";
                               head += "0082828800";
                               head += "0000";
                               head += "F1";
                               head += "000A";

                               String content = "";
                               content += "02";
                               byte[] s = BytesHelp.int2Bytes(serialNo, 2);
                               content += BytesHelp.byte2HexStr(s);
                               content += tsStr.substring(2);

                               content += BytesHelp.byte2HexStr(BytesHelp.subBytes(responsebuff,22,2));

                               content += "03";

                               byte[] headbuff = BytesHelp.hexStr2Bytes(head);
                               byte[] contentbuff = BytesHelp.hexStr2Bytes(content);

                               byte[] respPacket = BytesHelp.arrayApend(headbuff, contentbuff);//CRC16
                               crc16 = BytesHelp.crcFun2014(respPacket);
                               respPacket = BytesHelp.arrayApend(respPacket, crc16);


                               LogHelper.info("************* rtu send datagram F1 " + BytesHelp.byte2HexStr(respPacket));

                               outputStream.write(respPacket);

                               serialNo+=1;
                           }else  if(responsebuff[10] == (byte) 0xF4){
                               issend2f=false;

                               SimpleDateFormat timeFormat = new SimpleDateFormat("yyyyMMddHHmmss");
                               String tsStr = timeFormat.format(new Date());


                               String head = "7E7E";
                               head += "01";
                               head += "0082828800";
                               head += "0000";
                               head += "F4";
                               head += "000A";

                               String content = "";
                               content += "02";
                               byte[] s = BytesHelp.int2Bytes(serialNo, 2);
                               content += BytesHelp.byte2HexStr(s);
                               content += tsStr.substring(2);

                               content += BytesHelp.byte2HexStr(BytesHelp.subBytes(responsebuff,22,2));

                               content += "03";

                               byte[] headbuff = BytesHelp.hexStr2Bytes(head);
                               byte[] contentbuff = BytesHelp.hexStr2Bytes(content);

                               byte[] respPacket = BytesHelp.arrayApend(headbuff, contentbuff);//CRC16
                               crc16 = BytesHelp.crcFun2014(respPacket);
                               respPacket = BytesHelp.arrayApend(respPacket, crc16);


                               LogHelper.info("************* rtu send datagram F4 " + BytesHelp.byte2HexStr(respPacket));

                               outputStream.write(respPacket);

                               serialNo+=1;
                           }

                       }
                   }
                   Thread.sleep(200);

               }catch (Exception e){
                   outputStream.close();

                  input.close();

                   socket.close();
                   socket=null;
               }
            }




        } catch (Exception e) {
            e.printStackTrace();
        }finally {

            LogHelper.info("end****************");
        }
        return 0;
    }
}
