package com.tykj.dev.rfid.timeTask;

import cn.pda.serialport.Tools;
import com.module.interaction.ReaderHelper;
import com.rfid.RFIDReaderHelper;
import com.rfid.ReaderConnector;
import com.rfid.config.CMD;
import com.rfid.config.ERROR;
import com.rfid.rxobserver.RXObserver;
import com.rfid.rxobserver.bean.RXInventoryTag;
import com.rfid.rxobserver.bean.RXOperationTag;
import com.util.StringTool;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Observer;

/**
 * @author HuangXiahao
 * @version V1.0
 * @class Thread
 * @packageName com.tykj.dev.rfid.timeTask
 **/
@Slf4j
public class InventoryThread extends Thread {

    private static int CURRENT_READ_POINT = 0;

    private final int ANT_COUNT = 2;
    /**
     * 每次盘存的临时变量
     */
    ArrayList<String> strEpcArray = new ArrayList<>();
    ArrayList<String> strTidArray = new ArrayList<>();
    /**
     * 读写器 连接器
     */
    ReaderConnector mConnector = new ReaderConnector();
    Boolean runFlag = true;
    ReaderHelper mReaderHelper;
    private int currentAnt = 0;
    Observer mObserver = new RXObserver() {

        /**
         * 当标签盘存完成后会先执行这个方法
         * 本方法盘存到多个标签会执行多次
         * @param tag
         */
        @Override
        protected void onInventoryTag(RXInventoryTag tag) {
            //将EPC添加至List中
            if (!strEpcArray.contains(tag.strEPC)) {
                strEpcArray.add(tag.strEPC);
            }

        }

        /**
         * onInventoryTag 执行完后会执行这段代码
         * 盘存到多个标签，会等所有的onInventoryTag执行完 再执行这里
         * @param endTag
         */
        @Override
        protected void onInventoryTagEnd(RXInventoryTag.RXInventoryTagEnd endTag) {
            //将阅读指针置为0
            CURRENT_READ_POINT = 0;
            //读取标签
            changeEpcMath();
        }

        /**
         * 出现错误时运行这里
         * @param cmd
         * @param status
         */
        @Override
        protected void onExeCMDStatus(byte cmd, byte status) {
            if (cmd == CMD.SET_WORK_ANTENNA && status == ERROR.SUCCESS) {
                //天线已经被设置  开始盘存
                System.out.println("天线切换成功");
                inventory();
            } else if (cmd == CMD.SET_ACCESS_EPC_MATCH && status == ERROR.SUCCESS) {
                //EPC已经被设置  开始盘存
                System.out.println("EPC已经设置成功，当前EPC为：" + strEpcArray.get(CURRENT_READ_POINT));
                readTag();
            } else
                //读取标签，未读取到结果
                if (cmd == CMD.READ_TAG) {
                    readTag();
                } else {
                    System.out.println("cmd:" + cmd);
                }


        }

        /**
         * 每个标签读取完成时会运行这里
         * @param tag
         */
        @Override
        protected void onOperationTag(RXOperationTag tag) {
            // 12 34 45 -> 123445
            String tid = tag.strData.replaceAll(" ", "");
            //如果不存在就往结果数组里添加元素
            if (!strTidArray.contains(tid)) {
                strTidArray.add(tid);
            }
            //将标签的读取指针向后移动一位
            CURRENT_READ_POINT++;
            // 如果指针小于或者等于 盘存到的epc数量则继续读取 读取下一个标签
            if (CURRENT_READ_POINT < strEpcArray.size()) {
                changeEpcMath();
            } else {
                System.out.println("本次盘存标签EPC数量：" + strEpcArray.size());
                System.out.println("现存标签TID数量：" + strTidArray.size());
                //清空本次盘存的EPC
                strEpcArray.clear();
                //如果运行标记为true的话 设置天线 继续运行
                if (runFlag) {
                    //如果天线总数大于1 就切换天线   否则开始下一次读取
                    if (ANT_COUNT > 1) {
                        moveAntToNext();
                    } else {
                        changeEpcMath();
                    }
                }
            }
        }
    };

    private void moveAntToNext() {
        currentAnt = ++currentAnt % ANT_COUNT;
        changeAnt(currentAnt);
    }


    @Override
    public void run() {
        mReaderHelper = mConnector.connectNet("192.168.0.178", 4001);
        if (mReaderHelper != null) {
            try {
                mReaderHelper.registerObserver(mObserver);
                //默认切换到默认天线
                changeAnt(currentAnt);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } else {
            log.error("连接天线失败");
            mConnector.disConnect();
        }
    }

    /**
     * 盘存指令
     */
    private void inventory() {
        ((RFIDReaderHelper) mReaderHelper).realTimeInventory((byte) 0xff, (byte) 0x01);
    }

    /**
     * 读取List里的所有标签详情
     */
    public void readTag() {
        byte[] pass = Tools.HexString2Bytes("00000000");
        ((RFIDReaderHelper) mReaderHelper).readTag((byte) 0xFF, (byte) 0x02, (byte) 0x00, (byte) 0x06, pass);
    }

    /**
     * 设置EPC编码
     */
    private void changeEpcMath() {
        if (strEpcArray.size() > 0) {
            //修改当前EPC
            byte[] bytes = StringTool.stringToByteArray(strEpcArray.get(CURRENT_READ_POINT));
            ((RFIDReaderHelper) mReaderHelper).setAccessEpcMatch((byte) 0x01, (byte) bytes.length, bytes);
        } else {
            moveAntToNext();
        }
    }


    /**
     * 切换天线
     *
     * @param currentAnt 天线ID 1-16
     */
    public void changeAnt(int currentAnt) {
        System.out.println("切换天线至：" + currentAnt);
        ((RFIDReaderHelper) mReaderHelper).setWorkAntenna((byte) 0x01, (byte) currentAnt);
    }

    public void setRunFlag(Boolean runFlag) {
        this.runFlag = runFlag;
    }

    public ArrayList<String> getStrTidArray() {
        return strTidArray;
    }

    public ReaderHelper getmReaderHelper() {
        return mReaderHelper;
    }

    public ReaderConnector getmConnector() {
        return mConnector;
    }
}
