/// <summary>
 /// Creates a new raw data object <paramref name="data"/> for the element specified by <paramref name="info"/>.
 /// </summary>
 /// <param name="data">The raw data to upload.</param>
 /// <param name="info">The <see cref="RawDataInformationDto"/> object containing the <see cref="RawDataEntityDto"/> type and the uuid of the raw data that should be uploaded.</param>
 /// <param name="cancellationToken">A token to cancel the asynchronous operation.</param>
 /// <remarks>
 /// If key speciefied by <see cref="RawDataInformationDto.Key"/> is -1, a new key will be chosen by the server automatically. This is the preferred way.
 /// </remarks>
 /// <exception cref="ArgumentNullException"><paramref name="info"/> or <paramref name="data"/> is <see langword="null" />.</exception>
 public Task CreateRawData(RawDataInformationDto info, byte[] data, CancellationToken cancellationToken = default)
 {
     if (info == null)
     {
         throw new ArgumentNullException(nameof(info));
     }
     if (data == null)
     {
         throw new ArgumentNullException(nameof(data));
     }
     return(UploadRawData(info, data, HttpMethod.Post, cancellationToken));
 }
        private Task UploadRawData(RawDataInformationDto info, byte[] data, HttpMethod method, CancellationToken cancellationToken)
        {
            StringUuidTools.CheckUuid(info.Target.Entity, info.Target.Uuid);

            if (string.IsNullOrEmpty(info.FileName))
            {
                throw new ArgumentException("FileName needs to be set.", nameof(info));
            }

            var requestString = info.Key.HasValue && info.Key >= 0
                                ? $"rawData/{info.Target.Entity}/{info.Target.Uuid}/{info.Key}"
                                : $"rawData/{info.Target.Entity}/{info.Target.Uuid}";

            var stream = new MemoryStream(data, 0, data.Length, false, true);

            return(_RestClient.Request(RequestBuilder.CreateWithAttachment(method, requestString, stream, info.MimeType, info.Size, info.MD5, info.FileName), cancellationToken));
        }
        /// <summary>
        /// Updates the raw data object <paramref name="data"/> for the element identified by <paramref name="info"/>.
        /// </summary>
        /// <param name="data">The raw data to upload.</param>
        /// <param name="info">The <see cref="RawDataInformationDto"/> object containing the <see cref="RawDataEntityDto"/> type, the uuid and the key of the raw data that should be updated.</param>
        /// <param name="cancellationToken">A token to cancel the asynchronous operation.</param>
        /// <exception cref="ArgumentNullException"><paramref name="info"/> is <see langword="null" />.</exception>
        public Task UpdateRawData(RawDataInformationDto info, byte[] data, CancellationToken cancellationToken = default)
        {
            if (info == null)
            {
                throw new ArgumentNullException(nameof(info));
            }

            if (info.Key < 0)
            {
                throw new InvalidOperationException("Unable to update raw data object: A key must be specified.");
            }
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data), "Unable to update raw data object: Data object is null.");
            }

            return(UploadRawData(info, data, HttpMethod.Put, cancellationToken));
        }
        /// <summary>
        /// Deletes the raw data object identified by the <paramref name="info"/>.
        /// </summary>
        /// <param name="info">The raw data entry to delete.</param>
        /// <param name="client">The client class to use.</param>
        /// <param name="cancellationToken">A token to cancel the asynchronous operation.</param>
        /// <exception cref="ArgumentNullException"><paramref name="client"/> or <paramref name="info"/> is <see langword="null" />.</exception>
        public static Task DeleteRawData([NotNull] this IRawDataServiceRestClient client, [NotNull] RawDataInformationDto info, CancellationToken cancellationToken = default)
        {
            if (client == null)
            {
                throw new ArgumentNullException(nameof(client));
            }
            if (info == null)
            {
                throw new ArgumentNullException(nameof(info));
            }

            return(client.DeleteRawData(info.Target, info.Key, cancellationToken));
        }
        /// <summary>
        /// Fetches raw data as a byte array for the raw data item identified by <paramref name="info"/>.
        /// </summary>
        /// <param name="client">The client class to use.</param>
        /// <param name="info">The <see cref="RawDataInformationDto"/> that specifies the raw data object that should be fetched.</param>
        /// <param name="cancellationToken">A token to cancel the asynchronous operation.</param>
        /// <exception cref="ArgumentNullException"><paramref name="client"/> or <paramref name="info"/> is <see langword="null" />.</exception>
        public static Task <byte[]> GetRawData([NotNull] this IRawDataServiceRestClient client, [NotNull] RawDataInformationDto info, CancellationToken cancellationToken = default)
        {
            if (client == null)
            {
                throw new ArgumentNullException(nameof(client));
            }
            if (info == null)
            {
                throw new ArgumentNullException(nameof(info));
            }

            return(client.GetRawData(info.Target, info.Key.GetValueOrDefault(), info.MD5, cancellationToken));
        }