package com.pwt.netty.common.vehicle2;

import com.pwt.netty.common.Codeable;
import com.pwt.netty.util.ByteBufUtil;
import io.netty.buffer.ByteBuf;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

import java.nio.charset.StandardCharsets;


@Data
@EqualsAndHashCode
@ToString
public abstract class Vehicle2Message implements Codeable {

    public static final int MAGIC = 0x682324;
    public static final int MAGIC_LENGTH = 3;
    public static final int VIN_LENGTH = 17;

    public static final int BATTERY_SN_LENGTH = 24;

    public static final int MAGIC_END = 0x68;

    private final byte type;
    private String vin;

    /**
     * 读取协议中规定的长度，用于封帧验证
     * @return 协议中规定的长度
     */
    public abstract int getProtocolLength();

    @Override
    public final void encode(ByteBuf byteBuf) throws Exception {
        // magic header 3 byte
        byteBuf.writeMedium(Vehicle2Message.MAGIC);
        // length 2 byte
        byteBuf.writeShortLE(getProtocolLength());
        // type 1 byte
        byteBuf.writeByte(type);
        // vin 17 byte
        ByteBufUtil.WriteString(byteBuf, vin, VIN_LENGTH, "0");
        encodeInternal(byteBuf);

        // end 1 byte
        byteBuf.writeByte(MAGIC_END);
    }

    @Override
    public final void decode(ByteBuf byteBuf) throws Exception {
        this.vin = byteBuf.readCharSequence(VIN_LENGTH, StandardCharsets.US_ASCII).toString();
        decodeInternal(byteBuf);
    }

    protected abstract void encodeInternal(ByteBuf byteBuf) throws Exception;
    protected abstract void decodeInternal(ByteBuf byteBuf) throws Exception;
}
