namespace OF_DL.Widevine;

internal class PSSHBox
{
    private static readonly byte[] PSSH_HEADER = new byte[] { 0x70, 0x73, 0x73, 0x68 };

    private PSSHBox(List<byte[]> kids, byte[] data)
    {
        KIDs = kids;
        Data = data;
    }

    public List<byte[]> KIDs { get; set; } = new();
    public byte[] Data { get; set; }

    public static PSSHBox FromByteArray(byte[] psshbox)
    {
        using MemoryStream stream = new(psshbox);

        stream.Seek(4, SeekOrigin.Current);
        byte[] header = new byte[4];
        stream.Read(header, 0, 4);

        if (!header.SequenceEqual(PSSH_HEADER))
        {
            throw new Exception("Not a pssh box");
        }

        stream.Seek(20, SeekOrigin.Current);
        byte[] kidCountBytes = new byte[4];
        stream.Read(kidCountBytes, 0, 4);

        if (BitConverter.IsLittleEndian)
        {
            Array.Reverse(kidCountBytes);
        }

        uint kidCount = BitConverter.ToUInt32(kidCountBytes);

        List<byte[]> kids = new();
        for (int i = 0; i < kidCount; i++)
        {
            byte[] kid = new byte[16];
            stream.Read(kid);
            kids.Add(kid);
        }

        byte[] dataLengthBytes = new byte[4];
        stream.Read(dataLengthBytes);

        if (BitConverter.IsLittleEndian)
        {
            Array.Reverse(dataLengthBytes);
        }

        uint dataLength = BitConverter.ToUInt32(dataLengthBytes);

        if (dataLength == 0)
        {
            return new PSSHBox(kids, []);
        }

        byte[] data = new byte[dataLength];
        stream.Read(data);

        return new PSSHBox(kids, data);
    }
}
