package com.grigowashere.aismap.ble.hub;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

/**
 * One DATA notify frame: 10-byte header + payload.
 */
public class AisHubFrame {
    public final int protocolVersion;
    public final int msgType;
    public final int sessionMsgId;
    public final int chunkIndex;
    public final int chunkCount;
    public final byte[] payload;

    public AisHubFrame(int protocolVersion, int msgType, int sessionMsgId,
                       int chunkIndex, int chunkCount, byte[] payload) {
        this.protocolVersion = protocolVersion;
        this.msgType = msgType;
        this.sessionMsgId = sessionMsgId;
        this.chunkIndex = chunkIndex;
        this.chunkCount = chunkCount;
        this.payload = payload;
    }

    /**
     * @return null if buffer too short or truncated
     */
    public static AisHubFrame parse(byte[] buf) {
        if (buf == null || buf.length < AisHubConstants.HEADER_SIZE) {
            return null;
        }
        ByteBuffer bb = ByteBuffer.wrap(buf).order(ByteOrder.LITTLE_ENDIAN);
        int pv = bb.get() & 0xFF;
        int mt = bb.get() & 0xFF;
        int sid = bb.getShort() & 0xFFFF;
        int cidx = bb.getShort() & 0xFFFF;
        int ccnt = bb.getShort() & 0xFFFF;
        int plen = bb.getShort() & 0xFFFF;
        if (buf.length < AisHubConstants.HEADER_SIZE + plen) {
            return null;
        }
        byte[] payload = new byte[plen];
        System.arraycopy(buf, AisHubConstants.HEADER_SIZE, payload, 0, plen);
        return new AisHubFrame(pv, mt, sid, cidx, ccnt, payload);
    }
}
