package cn.estsh.i3plus.ext.mes.pcn.apiservice.util.reader;

import lombok.Getter;
import lombok.Setter;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @author ns
 * @create 2021/11/29 0029 下午 18:06
 * 发送命令包model
 */
public class RequestPacketModel {

    /**
     * 引导码
     */
    @Getter
    private final Byte bootCode = ReaderConstWords.REQUEST_BOOT_CODE;

    /**
     * 包有效长度，该长度为后3个部分的总字节数
     */
    @Getter
    private Byte length;

//    /**
//     * 读写器地址 读写器地址,1～254，0和255为广播地址,可以为空
//     */
//    @Getter
//    @Setter
//    private Byte address;

    /**
     *
     */
    @Getter
    @Setter
    private Byte command;

    /**
     * 校验和
     */
    @Getter
    private Byte checkSum;

    /**
     * 命令参数数组
     */
    @Getter
    @Setter
    private IBaseCommandParam commandParams;


    public RequestPacketModel buildListTagIdCommand(ComandListTagId comandListTagId) {
        //40  06  EE  mem  addr  LEN  Mask  CheckSum
        this.command = ReaderConstWords.LIST_TAG_COMMAND;
        if (null == comandListTagId) {
            return null;
        }
        final RequestPacketModel comandListTagIdRequestPacketModel = this;
        comandListTagIdRequestPacketModel.setCommandParams(comandListTagId);
        this.length = this.getLength();
        this.checkSum = checkSum();
        return comandListTagIdRequestPacketModel;
    }

    /**
     * 构造默认获取标签id的
     *
     * @return
     */
    public RequestPacketModel buildListTagIdCommand() {
        //40  06  EE  mem  addr  LEN  Mask  CheckSum
        this.command = ReaderConstWords.LIST_TAG_COMMAND;
        ComandListTagId comandListTagId = ComandListTagId.getDefaultInstance();
//        comandListTagId.setLen(ReaderConstWords.BYTE_ZERO);
//        comandListTagId.setMask(ReaderConstWords.BYTE_ZERO);
//        comandListTagId.setAddr(ReaderConstWords.BYTE_ZERO);
//        comandListTagId.setMem(ReaderConstWords.DEFAULT_DATA_AREA);
        this.setCommandParams(comandListTagId);
        this.length = this.getLength();
        this.checkSum = checkSum();
        return this;
    }

    /**
     * 构造默认获取标签数据的packet
     *
     * @return
     */
    public RequestPacketModel buildReadTagCommand(Byte[] tags) {
        this.command = ReaderConstWords.READ_TAG_COMMAND;
        CommandReadTag commandReadTag = new CommandReadTag(tags);
        this.setCommandParams(commandReadTag);
        this.length = this.getLength();
        this.checkSum = checkSum();
        return this;
    }

    public RequestPacketModel buildReadTagCommand(Byte[] tags, byte mem) {
        this.command = ReaderConstWords.READ_TAG_COMMAND;
        CommandReadTag commandReadTag = new CommandReadTag(tags, mem);
        this.setCommandParams(commandReadTag);
        this.length = this.getLength();
        this.checkSum = checkSum();
        return this;
    }

    /**
     * 获取数据包的有效长度
     * @return
     */
    public byte getLength(){
        return (byte) (2 + this.commandParams.getLength());
    }

    /**
     * 获取传入数据的校验和
     *
     * @param bytes
     * @return
     */
    public Byte checkSum(byte[] bytes) {
        byte result = 0;
        if (null == bytes || bytes.length == 0) {
            return result;
        }

        for (int i = 0; i < bytes.length; i++) {
            result += bytes[i];
        }
        result = (byte) (~result + 1);
        return result;

    }


    /**
     * 获取当前packet的校验和
     *
     * @return
     */
    private Byte checkSum() {
//        byte result = (byte) (this.bootCode + this.length + this.address + this.command);
        byte result = (byte) (this.bootCode + this.length  + this.command);
        if (!ObjectUtils.isEmpty(this.commandParams)) {
            for (byte parameter : this.commandParams.toByteArray()) {
                result += parameter;
            }
        }
        result = (byte) (~result + 1);
        return result;
    }

    public RequestPacketModel() {
        this.length = ReaderConstWords.BYTE_ZERO;
//        this.address = ReaderConstWords.BYTE_ZERO;
        this.command = ReaderConstWords.BYTE_ZERO;
        this.checkSum = ReaderConstWords.BYTE_ZERO;
    }

    public RequestPacketModel(IBaseCommandParam commandParams) {
        this.length = ReaderConstWords.BYTE_ZERO;
//        this.address = ReaderConstWords.BYTE_ZERO;
        this.command = ReaderConstWords.BYTE_ZERO;
        this.checkSum = ReaderConstWords.BYTE_ZERO;
        this.commandParams = commandParams;
    }

    /**
     * 将当前的属性转换成ByteList
     * @return
     */
    public List<Byte> toByteList() {
        List<Byte> byteList = new ArrayList<>();
        byteList.add(this.bootCode);
        byteList.add(this.length);
        byteList.add(this.command);
//        byteList.add(this.address);
        byteList.addAll(this.commandParams.toByteList());
        byteList.add(this.checkSum);
        return byteList;
    }

    /**
     * 将packet转换成Byte 数组
     * @return
     */
    public byte[] toByteArray() {
        byte[] bytes = new byte[this.toByteList().size()];
        for (int i = 0 ;i<bytes.length;i++){
            bytes[i] = this.toByteList().get(i);
        };
       return bytes;
    }

    public static void main(String[] args) {
        ComandListTagId comandListTagId = ComandListTagId.getDefaultInstance();
        RequestPacketModel requestPacketModel = new RequestPacketModel();
        System.out.println(ReaderUtil.bytes2HexString(requestPacketModel.buildListTagIdCommand().toByteArray()));

        RequestPacketModel requestPacketModel2 = new RequestPacketModel();
        System.out.println(ReaderUtil.bytes2HexString(requestPacketModel2.buildListTagIdCommand().toByteArray()));

        RequestPacketModel requestPacketModel3 = new RequestPacketModel();
        Byte[] tags = new Byte[]{(byte)0xcb,(byte)0x9f};
        requestPacketModel3 = requestPacketModel3.buildReadTagCommand(tags);
        System.out.println(ReaderUtil.bytes2HexString(requestPacketModel3.toByteArray()));

        //40H  03H  01H  04H  B8H
        byte[] result = new byte[]{(byte) 0xf0,0x02,0x01,0x0d,0x09};

        System.out.println(ReaderUtil.isSuccess(result));
        System.out.println(ReaderUtil.bytes2HexString(ReaderUtil.getTags(result)));

    }
}
