package com.gyee.protocol.gyfp2.message;

import com.gyee.edge.common.utils.BytesUtils;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class MessageData implements Serializable {
    private int dataKey;
    private long ts;
    private byte dataType;

    private Optional<Boolean> GYFP2_TYPE_BOOLEAN ; //Boolean 类型 0
    private Optional<Float>  GYFP2_TYPE_FLOAT32;  //32 位浮点数 10
    private Optional<Long> GYFP2_TYPE_INT64;  //无符号 64 位整数 8
    private Optional<Double> GYFP2_TYPE_FLOAT64; //64 位浮点数 11
    /*private byte GYFP2_TYPE_INT8;  //有符号 8 位整数 1
    private byte GYFP2_TYPE_UINT8; //无符号 8 位整数 2
    private short GYFP2_TYPE_INT16; //有符号 16 位整数 3
    private char GYFP2_TYPE_UINT16;  //无符号 16 位整数 4
    private float GYFP2_TYPE_INT32; //有符号 32 位整数 5
    private int GYFP2_TYPE_UINT32; //无符号 32 位整数 6
    private long GYFP2_TYPE_UINT64; //无符号 32 位整数 7
    private char GYFP2_TYPE_FLOAT16; //16 位浮点数 9
    private String GYFP2_TYPE_STRING;  //字符串类型 12
    private boolean GYFP2_TYPE_BIT;  //位 15  */


    public byte[] ValuetoBytes(byte type){
        ByteBuf buffer = Unpooled.buffer(10);
        if (type==0){
            buffer.writeBoolean(GYFP2_TYPE_BOOLEAN.get());
        }else if(type==10){
            buffer.writeFloat(getGYFP2_TYPE_FLOAT32().get());
        }else if(type==8) {
            buffer.writeLong(getGYFP2_TYPE_INT64().get());
        }else if(type==11){
            buffer.writeDouble(getGYFP2_TYPE_FLOAT64().get());
        /*else if(type==1){
            buffer.writeByte(getGYFP2_TYPE_INT8());
        }else if(type==2){
            buffer.writeByte(getGYFP2_TYPE_UINT8());
        }else if(type==3){
            buffer.writeByte(getGYFP2_TYPE_INT16());
        }else if(type==4){
            buffer.writeByte(getGYFP2_TYPE_UINT16());
        }else if(type==5){
            buffer.writeFloat(getGYFP2_TYPE_INT32());
        }else if(type==6){
            buffer.writeInt(getGYFP2_TYPE_UINT32());
        }else if(type==7){
            buffer.writeLong(getGYFP2_TYPE_INT64());
        }else if(type==8){
            buffer.writeLong(getGYFP2_TYPE_UINT64());
        }else if(type==9){
            buffer.writeChar(getGYFP2_TYPE_FLOAT16());
        }else if(type==11){
            buffer.writeDouble(getGYFP2_TYPE_FLOAT64());
        }else if(type==15){
            buffer.writeBoolean(isGYFP2_TYPE_BIT());
        }*/
        }
        byte[] bytes = ByteBufUtil.getBytes(buffer);
        return bytes;
    }

    //MessageData对象转字节数组   messagetype决定实际长度类型
    // mutable中有值则采用mutable中type的值，mutable中无值则采用messagedata中的datatype。
    public byte[] toBytes(int attribute,byte messagetype){
        ByteBuf buffer = Unpooled.buffer(10);
        if (attribute==0){
            buffer.writeByte(getDataType());
            buffer.writeBytes(BytesUtils.intToByte2(getDataKey()));
            buffer.writeLong(getTs());
            buffer.writeBytes(ValuetoBytes(getDataType()));
        }else if(attribute==1){
            buffer.writeByte(getDataType());
            buffer.writeLong(getTs());
            buffer.writeBytes(ValuetoBytes(getDataType()));
        }else if(attribute==2) {
            buffer.writeBytes(BytesUtils.intToByte2(getDataKey()));
            buffer.writeLong(getTs());
            buffer.writeBytes(ValuetoBytes(messagetype));
        }else if(attribute==3){
            buffer.writeLong(getTs());
            buffer.writeBytes(ValuetoBytes(messagetype));
        }else if(attribute==4){
            buffer.writeByte(getDataType());
            buffer.writeBytes(BytesUtils.intToByte2(getDataKey()));
            buffer.writeBytes(ValuetoBytes(getDataType()));
        }else if (attribute==5){
            buffer.writeByte(getDataType());
            buffer.writeBytes(ValuetoBytes(getDataType()));
        }else if (attribute==6){
            buffer.writeBytes(BytesUtils.intToByte2(getDataKey()));
            buffer.writeBytes(ValuetoBytes(messagetype));
        }else if (attribute==7){
            buffer.writeBytes(ValuetoBytes(messagetype));
        }
        byte[] bytes = ByteBufUtil.getBytes(buffer);
        return bytes;
    }


    //字节数组转MessageData对象
    public static List<MessageData> toMessageData(byte[] bytes, int attribute) {
        List<MessageData> messageDataList = new ArrayList<>();
        //获取data块字节大小
        if(attribute==0) {
            int count = bytes.length - 16;
            byte[] bytes1 = new byte[count];
            System.arraycopy(bytes, 16, bytes1, 0, count);
            for (int i = 0; i < bytes1.length;) {
                MessageData messageData = new MessageData();
                messageData.setDataType(bytes1[i]);
                messageData.setDataKey(BytesUtils.BytesToInt(bytes1,i+1));
                messageData.setTs(BytesUtils.getLong2(bytes1,i+4));
                if (bytes1[i]==0){
                    messageData.setGYFP2_TYPE_BOOLEAN(BytesUtils.getBoolean(bytes1,i+12));
                    i = i + 13;
                }else if (bytes1[i]==10){
                    messageData.setGYFP2_TYPE_FLOAT32(BytesUtils.getFloat(bytes1,i+12));
                    i = i + 16;
                }else if(bytes1[i]==8){
                    messageData.setGYFP2_TYPE_INT64(BytesUtils.getLong(bytes1,i+12));
                    i = i + 20;
                }else if(bytes1[i]==11){
                    messageData.setGYFP2_TYPE_FLOAT64(BytesUtils.getDouble(bytes1,i+12));
                    i = i + 20;
                }
                messageDataList.add(messageData);
            }
        } else if(attribute==1){
            int count = bytes.length - 19;
            byte[] bytes1 = new byte[count];
            System.arraycopy(bytes, 19, bytes1, 0, count);
            for (int i = 0; i < bytes1.length;) {
                MessageData messageData = new MessageData();
                messageData.setDataType(bytes1[i]);
                messageData.setTs(BytesUtils.getLong2(bytes1,i+1));
                if (bytes1[i]==0){
                    messageData.setGYFP2_TYPE_BOOLEAN(BytesUtils.getBoolean(bytes1,i+8));
                    i = i + 9;
                }else if (bytes1[i]==10){
                    messageData.setGYFP2_TYPE_FLOAT32(BytesUtils.getFloat(bytes1,i+8));
                    i = i + 12;
                }else if(bytes1[i]==8){
                    messageData.setGYFP2_TYPE_INT64(BytesUtils.getLong(bytes1,i+8));
                    i = i + 16;
                }else if(bytes1[i]==11){
                    messageData.setGYFP2_TYPE_FLOAT64(BytesUtils.getDouble(bytes1,i+8));
                    i = i + 16;
                }
                messageDataList.add(messageData);
            }
        }else if(attribute==2){
            byte[] bytes2 = new byte[1];
            System.arraycopy(bytes, 16, bytes2, 0, 1);
            byte[] bytes1 = new byte[bytes.length-(16 + bytes2.length)];
            System.arraycopy(bytes, 16 + bytes2.length, bytes1, 0, bytes1.length);
            for (int i = 0; i < bytes1.length;) {
                MessageData messageData = new MessageData();
                messageData.setDataKey(BytesUtils.BytesToInt(bytes1,i));
                messageData.setTs(BytesUtils.getLong2(bytes1,i+3));
                if (bytes2[0]==0){
                    messageData.setGYFP2_TYPE_BOOLEAN(BytesUtils.getBoolean(bytes1,i+11));
                    i = i + 12;
                }else if (bytes2[0]==10){
                    messageData.setGYFP2_TYPE_FLOAT32(BytesUtils.getFloat(bytes1,i+11));
                    i = i + 15;
                }else if(bytes2[0]==8){
                    messageData.setGYFP2_TYPE_INT64(BytesUtils.getLong(bytes1,i+11));
                    i = i + 19;
                }else if(bytes2[0]==11){
                    messageData.setGYFP2_TYPE_FLOAT64(BytesUtils.getDouble(bytes1,i+11));
                    i = i + 19;
                }
                messageDataList.add(messageData);
            }
        }else if(attribute==3){
            byte[] bytes2 = new byte[4];
            System.arraycopy(bytes, 16, bytes2, 0, 4);
            byte[] bytes1 = new byte[bytes.length-(16 + bytes2.length)];
            System.arraycopy(bytes, 16 + bytes2.length, bytes1, 0, bytes1.length);
            for (int i = 0; i < bytes1.length;) {
                MessageData messageData = new MessageData();
                messageData.setTs(BytesUtils.getLong2(bytes1,i));
                if (bytes2[0]==0){
                    messageData.setGYFP2_TYPE_BOOLEAN(BytesUtils.getBoolean(bytes1,i+8));
                    i = i + 9;
                }else if (bytes2[0]==10){
                    messageData.setGYFP2_TYPE_FLOAT32(BytesUtils.getFloat(bytes1,i+8));
                    i = i + 12;
                }else if(bytes2[0]==8){
                    messageData.setGYFP2_TYPE_INT64(BytesUtils.getLong(bytes1,i+8));
                    i = i + 16;
                }else if(bytes2[0]==11){
                    messageData.setGYFP2_TYPE_FLOAT64(BytesUtils.getDouble(bytes1,i+8));
                    i = i + 16;
                }
                messageDataList.add(messageData);
            }
        }else if(attribute==4){
            int count = bytes.length - 24;
            byte[] bytes1 = new byte[count];
            System.arraycopy(bytes, 24, bytes1, 0, count);
            for (int i = 0; i < bytes1.length;) {
                MessageData messageData = new MessageData();
                messageData.setDataType(bytes1[i]);
                messageData.setDataKey(BytesUtils.BytesToInt(bytes1,i+1));
                if (bytes1[i]==0){
                    messageData.setGYFP2_TYPE_BOOLEAN(BytesUtils.getBoolean(bytes1,i+4));
                    i = i + 5;
                }else if (bytes1[i]==10){
                    messageData.setGYFP2_TYPE_FLOAT32(BytesUtils.getFloat(bytes1,i+4));
                    i = i + 8;
                }else if(bytes1[i]==8){
                    messageData.setGYFP2_TYPE_INT64(BytesUtils.getLong(bytes1,i+4));
                    i = i + 12;
                }else if(bytes1[i]==11){
                    messageData.setGYFP2_TYPE_FLOAT64(BytesUtils.getDouble(bytes1,i+4));
                    i = i + 12;
                }
                messageDataList.add(messageData);
            }
        }else if(attribute==5){
            int count = bytes.length - 27;
            byte[] bytes1 = new byte[count];
            System.arraycopy(bytes, 27, bytes1, 0, count);
            for (int i = 0; i < bytes1.length;) {
                MessageData messageData = new MessageData();
                messageData.setDataType(bytes1[i]);
                if (bytes1[i]==0){
                    messageData.setGYFP2_TYPE_BOOLEAN(BytesUtils.getBoolean(bytes1,i+1));
                    i = i + 2;
                }else if (bytes1[i]==10){
                    messageData.setGYFP2_TYPE_FLOAT32(BytesUtils.getFloat(bytes1,i+1));
                    i = i + 5;
                }else if(bytes1[i]==8){
                    messageData.setGYFP2_TYPE_INT64(BytesUtils.getLong(bytes1,i+1));
                    i = i + 9;
                }else if(bytes1[i]==11){
                    messageData.setGYFP2_TYPE_FLOAT64(BytesUtils.getDouble(bytes1,i+1));
                    i = i + 9;
                }
                messageDataList.add(messageData);
            }
        }else if(attribute==6){
            byte[] bytes2 = new byte[9];
            System.arraycopy(bytes, 16, bytes2, 0, 9);
            byte[] bytes1 = new byte[bytes.length-(16 + bytes2.length)];
            System.arraycopy(bytes, 16 + bytes2.length, bytes1, 0, bytes1.length);
            for (int i = 0; i < bytes1.length;) {
                MessageData messageData = new MessageData();
                messageData.setDataKey(BytesUtils.BytesToInt(bytes1,i));
                if (bytes2[0]==0){
                    messageData.setGYFP2_TYPE_BOOLEAN(BytesUtils.getBoolean(bytes1,i+3));
                    i = i + 4;
                }else if (bytes2[0]==10){
                    messageData.setGYFP2_TYPE_FLOAT32(BytesUtils.getFloat(bytes1,i+3));
                    i = i + 7;
                }else if(bytes2[0]==8){
                    messageData.setGYFP2_TYPE_INT64(BytesUtils.getLong(bytes1,i+3));
                    i = i + 11;
                }else if(bytes2[0]==11){
                    messageData.setGYFP2_TYPE_FLOAT64(BytesUtils.getDouble(bytes1,i+3));
                    i = i + 11;
                }
                messageDataList.add(messageData);
            }
        }else if(attribute==7){
            byte[] bytes2 = new byte[12];
            System.arraycopy(bytes, 16, bytes2, 0, 12);
            byte[] bytes1 = new byte[bytes.length-(16 + bytes2.length)];
            System.arraycopy(bytes, 16 + bytes2.length, bytes1, 0, bytes1.length);
            for (int i = 0; i < bytes1.length;) {
                MessageData messageData = new MessageData();
                if (bytes2[0]==0){
                    messageData.setGYFP2_TYPE_BOOLEAN(BytesUtils.getBoolean(bytes1,i));
                    i = i + 1;
                }else if (bytes2[0]==10){
                    messageData.setGYFP2_TYPE_FLOAT32(BytesUtils.getFloat(bytes1,i));
                    i = i + 4;
                }else if(bytes2[0]==8){
                    messageData.setGYFP2_TYPE_INT64(BytesUtils.getLong(bytes1,i));
                    i = i + 8;
                }else if(bytes2[0]==11){
                    messageData.setGYFP2_TYPE_FLOAT64(BytesUtils.getDouble(bytes1,i));
                    i = i + 8;
                }
                messageDataList.add(messageData);
            }
        }
        return messageDataList;
    }
}
