package com.hboxs.serialport;

import android.os.SystemClock;
import android.util.Log;

import com.hboxs.serialport.frame.CommandFrame;
import com.hboxs.serialport.frame.ResponseFrame;
import com.hboxs.serialport.message.Message;
import com.hboxs.serialport.util.ByteUtils;

import org.greenrobot.eventbus.EventBus;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * 串口读取进程
 */
public class SerialPortReadThread extends Thread {
    private static final String TAG = "SerialPortReadThread";

    private BufferedInputStream mInputStream;

    private boolean running;

    public void setmName(String mName) {

    }


    public SerialPortReadThread(InputStream is) {

        mInputStream = new BufferedInputStream(is);
    }

    @Override
    public void run() {
        byte[] received = new byte[512];
        int size;

        Log.i(TAG, "开始读线程");

        running = true;

        while (running) {
            // 开启读list线程
            SerialPortSendQueue.startReadListThread();
            Log.d(TAG, "开启读list线程");
            try {
                int available = mInputStream.available();

                if (available > 0) {
                    size = mInputStream.read(received);
                    if (size > 0) {
//                        for (int i = 0; i < received.length; i++) {
//                            received[i] &= 0x7F; // 最高位强制置0
//                        }
                        onDataReceive(received, size);
                    }
                } else {
                    // 暂停一点时间，免得一直循环造成CPU占用率过高
                    SystemClock.sleep(10);
                }
            } catch (IOException e) {
                Log.e(TAG, "读取数据失败", e);
                running = false;
            }
        }

        close();
        Log.i(TAG, "结束读进程");
    }

    /**
     * 处理获取到的数据
     *
     * @param received
     * @param size
     */
    private void onDataReceive(byte[] received, int size) {
        // TODO: 解决粘包、分包等
        if (size == 1) {
            CommandFrame commandFrame = SerialPortSendQueue.getCurrentFrame();
            SerialPortSendQueue.setReceived();
            if (commandFrame==null){return;}
            switch (received[0]) {

                case Command.ACK:
                    try {
                        EventBus.getDefault().post(new Message("写入数据成功", Message.Type.ack,commandFrame.getId(),commandFrame.getAddress()));
                       // SerialPortSendQueue.setReceived();
                    }catch (NullPointerException e){
                        e.printStackTrace();
                    }
                    return;
                case Command.NAK:
                    Log.i(TAG, "收到指令：NAK");
                    try{
                        EventBus.getDefault().post(new Message("读/写数据无响应", Message.Type.nak,commandFrame.getId(),commandFrame.getAddress()));

                    }catch (NullPointerException e){
                        e.printStackTrace();
                    }
                    return;
                default:
            }
        } else if (size > 1) {
            CommandFrame commandFrame =SerialPortSendQueue.getCurrentFrame();
            SerialPortSendQueue.setReceived();
            if (commandFrame==null){return;}
            String hexStr = ByteUtils.bytes2HexStr(received, 0, size);
            int start = -1, end = -1;
            // 找帧数据,stx开始，etx结束
            for (int i = 0; i < size; i++) {
                if (received[i] == Command.STX) {
                    start = i + 1;
                } else if (received[i] == Command.ETX) {
                    end = i;
                    break;
                }
            }
            // start 和 end 整数表示收到的数据包包含帧数据
            if (start >= 0 && end >= 0) {
                byte[] data = new byte[]{};
                if (start < end) {
                    int len = end - start;
                    data = new byte[len];
                    System.arraycopy(received, start, data, 0, len);
                }
                ResponseFrame frame = new ResponseFrame();
                if (received.length > (end + 2)) {
                    frame.setOriSum(new byte[]{received[end + 1], received[end + 2]});
                }
                // 必须先设置校验和在设置数据，因为这一步会校验校验和
                frame.setData(data);
                try {
                    EventBus i = EventBus.getDefault();
                    String s = "";

                    Message event = new Message(frame, Message.Type.response, commandFrame.getId(), commandFrame.getAddress());
                    String s1 = "";

                    EventBus.getDefault().post(event);

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

    /**
     * 停止读线程
     */
    public void close() {
        try {
            mInputStream.close();
        } catch (IOException e) {
            Log.i(TAG, "异常", e);
        } finally {
            running = false;
        }
    }
}
