package com.usky.cdi.service.sip.rtp;

import lombok.Getter;

@Getter
public class RtpPacket {

    private int version;
    private boolean padding;
    private boolean extension;
    private int csrcCount;
    private boolean marker;
    private int payloadType;
    private int sequenceNumber;
    private long timestamp;
    private long ssrc;
    private byte[] payload;
    private int payloadOffset;
    private int payloadLength;

    public static RtpPacket parse(byte[] data, int length) {
        if (length < 12) {
            return null;
        }
        RtpPacket packet = new RtpPacket();
        int b0 = data[0] & 0xFF;
        packet.version = (b0 >> 6) & 0x03;
        packet.padding = ((b0 >> 5) & 0x01) == 1;
        packet.extension = ((b0 >> 4) & 0x01) == 1;
        packet.csrcCount = b0 & 0x0F;

        int b1 = data[1] & 0xFF;
        packet.marker = ((b1 >> 7) & 0x01) == 1;
        packet.payloadType = b1 & 0x7F;

        packet.sequenceNumber = ((data[2] & 0xFF) << 8) | (data[3] & 0xFF);
        packet.timestamp = ((data[4] & 0xFFL) << 24) | ((data[5] & 0xFFL) << 16)
                | ((data[6] & 0xFFL) << 8) | (data[7] & 0xFFL);
        packet.ssrc = ((data[8] & 0xFFL) << 24) | ((data[9] & 0xFFL) << 16)
                | ((data[10] & 0xFFL) << 8) | (data[11] & 0xFFL);

        int headerLength = 12 + packet.csrcCount * 4;
        if (packet.extension && length > headerLength + 4) {
            int extLen = ((data[headerLength + 2] & 0xFF) << 8 | (data[headerLength + 3] & 0xFF)) * 4;
            headerLength += 4 + extLen;
        }
        if (headerLength >= length) {
            return null;
        }

        packet.payload = data;
        packet.payloadOffset = headerLength;
        packet.payloadLength = length - headerLength;

        if (packet.padding && packet.payloadLength > 0) {
            int padLen = data[length - 1] & 0xFF;
            packet.payloadLength -= padLen;
        }
        return packet;
    }
}
