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

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;

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

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

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

    /**
     * 生产线代码
     */
    @Getter
    @Setter
    private String workCenterCode;

    /**
     * 工位代码
     */
    @Getter
    @Setter
    private String workCellCode;

    /**
     * 构造默认获取标签id的
     *
     * @return
     */
    public RequestPacketModel buildListTagIdCommand(byte mem, String workCenterCode, String workCellCode) {
        //40  06  EE  mem  addr  LEN  Mask  CheckSum
        this.command = ReaderConstWords.LIST_TAG_COMMAND;
        ComandListTagId comandListTagId = ComandListTagId.getInstance(mem);
        this.setCommandParams(comandListTagId);
        this.length = this.getLength();
        this.checkSum = checkSum();
        this.workCenterCode = workCenterCode;
        this.workCellCode = workCellCode;
        return this;
    }

    /**
     * 构造默认获取标签数据的packet
     *
     * @return
     */
    public RequestPacketModel buildReadTagCommand(Byte[] tags, byte mem, byte len, String workCenterCode, String workCellCode) {
        this.command = ReaderConstWords.READ_TAG_COMMAND;
        CommandReadTag commandReadTag = new CommandReadTag(tags, mem, len);
        this.setCommandParams(commandReadTag);
        this.length = this.getLength();
        this.checkSum = checkSum();
        this.workCenterCode = workCenterCode;
        this.workCellCode = workCellCode;
        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.command = ReaderConstWords.BYTE_ZERO;
        this.checkSum = ReaderConstWords.BYTE_ZERO;
    }

    public RequestPacketModel(IBaseCommandParam commandParams) {
        this.length = 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.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;
    }

}
