/// <summary>
        ///     Decodes a lavalink track identifier.
        /// </summary>
        /// <param name="buffer">the raw track identifier</param>
        /// <param name="verify">a value indicating whether the track header should be verified</param>
        /// <returns>the decoded track info</returns>
        /// <exception cref="InvalidOperationException">thrown if the track header is invalid</exception>
        /// <exception cref="ArgumentNullException">
        ///     thrown if the specified <paramref name="buffer"/> is <see langword="null"/>.
        /// </exception>
        public static LavalinkTrackInfo DecodeTrackInfo(byte[] buffer, bool verify = true)
        {
            if (buffer is null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            using (var memoryStream = new MemoryStream(buffer))
                using (var reader = new DataInputReader(memoryStream))
                {
                    ReadHeader(reader, buffer.Length, verify);

                    var title      = reader.ReadString();
                    var author     = reader.ReadString();
                    var length     = reader.ReadInt64();
                    var identifier = reader.ReadString();
                    var isStream   = reader.ReadBoolean();
                    var uri        = reader.ReadBoolean() ? reader.ReadString() : null;

                    return(new LavalinkTrackInfo
                    {
                        Title = title,
                        Author = author,
                        Duration = TimeSpan.FromMilliseconds(length),
                        TrackIdentifier = identifier,
                        IsLiveStream = isStream,
                        IsSeekable = !isStream,
                        Source = uri
                    });
                }
        }
        /// <summary>
        ///     Reads the track header.
        /// </summary>
        /// <param name="reader">the reader to read from</param>
        /// <param name="length">the length of raw binary data</param>
        /// <param name="verify">a value indicating whether the track header should be verified</param>
        /// <exception cref="InvalidOperationException">thrown if the track header is invalid</exception>
        /// <exception cref="ArgumentNullException">
        ///     thrown if the specified <paramref name="reader"/> is <see langword="null"/>.
        /// </exception>
        private static void ReadHeader(DataInputReader reader, int length, bool verify = true)
        {
            if (reader is null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            // the header is four bytes long, subtract
            length -= 4;

            var header     = reader.ReadInt32();
            var flags      = (int)((header & 0xC0000000L) >> 30);
            var hasVersion = (flags & 1) != 0;
            var version    = hasVersion ? reader.ReadSByte() : 1;
            var size       = header & 0x3FFFFFFF;

            // verify size
            if (verify && size != length)
            {
                throw new InvalidOperationException($"Error while verifying track header: Track Identifier length was {length}, but expected: {size}");
            }

            // verify version
            if (verify && version != 2)
            {
                throw new InvalidOperationException($"Error while verifying track header: Invalid track version: Was: {version}, expected: 2.");
            }
        }