// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.

package generated

import (
	"context"
	"encoding/base64"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
	"io"
	"net/http"
	"strconv"
	"strings"
	"time"
)

// BlockBlobClient contains the methods for the BlockBlob group.
// Don't use this type directly, use a constructor function instead.
type BlockBlobClient struct {
	internal *azcore.Client
	endpoint string
	version  string
}

// CommitBlockList - The Commit Block List operation writes a blob by specifying the list of block IDs that make up the blob.
// In order to be written as part of a blob, a block must have been successfully written to the
// server in a prior Put Block operation. You can call Put Block List to update a blob by uploading only those blocks that
// have changed, then committing the new and existing blocks together. You can do
// this by specifying whether to commit a block from the committed block list or from the uncommitted block list, or to commit
// the most recently uploaded version of the block, whichever list it may
// belong to.
// If the operation fails it returns an *azcore.ResponseError type.
//   - blocks - Blob Blocks.
//   - options - BlockBlobClientCommitBlockListOptions contains the optional parameters for the BlockBlobClient.CommitBlockList
//     method.
//   - BlobHTTPHeaders - BlobHTTPHeaders contains a group of parameters for the BlobClient.SetHTTPHeaders method.
//   - LeaseAccessConditions - LeaseAccessConditions contains a group of parameters for the ContainerClient.GetProperties method.
//   - CPKInfo - CPKInfo contains a group of parameters for the BlobClient.Download method.
//   - CPKScopeInfo - CPKScopeInfo contains a group of parameters for the BlobClient.SetMetadata method.
//   - ModifiedAccessConditions - ModifiedAccessConditions contains a group of parameters for the ContainerClient.Delete method.
func (client *BlockBlobClient) CommitBlockList(ctx context.Context, blocks BlockLookupList, options *BlockBlobClientCommitBlockListOptions, blobHTTPHeaders *BlobHTTPHeaders, leaseAccessConditions *LeaseAccessConditions, cpkInfo *CPKInfo, cpkScopeInfo *CPKScopeInfo, modifiedAccessConditions *ModifiedAccessConditions) (BlockBlobClientCommitBlockListResponse, error) {
	var err error
	req, err := client.commitBlockListCreateRequest(ctx, blocks, options, blobHTTPHeaders, leaseAccessConditions, cpkInfo, cpkScopeInfo, modifiedAccessConditions)
	if err != nil {
		return BlockBlobClientCommitBlockListResponse{}, err
	}
	httpResp, err := client.internal.Pipeline().Do(req)
	if err != nil {
		return BlockBlobClientCommitBlockListResponse{}, err
	}
	if !runtime.HasStatusCode(httpResp, http.StatusCreated) {
		err = runtime.NewResponseError(httpResp)
		return BlockBlobClientCommitBlockListResponse{}, err
	}
	resp, err := client.commitBlockListHandleResponse(httpResp)
	return resp, err
}

// commitBlockListCreateRequest creates the CommitBlockList request.
func (client *BlockBlobClient) commitBlockListCreateRequest(ctx context.Context, blocks BlockLookupList, options *BlockBlobClientCommitBlockListOptions, blobHTTPHeaders *BlobHTTPHeaders, leaseAccessConditions *LeaseAccessConditions, cpkInfo *CPKInfo, cpkScopeInfo *CPKScopeInfo, modifiedAccessConditions *ModifiedAccessConditions) (*policy.Request, error) {
	req, err := runtime.NewRequest(ctx, http.MethodPut, client.endpoint)
	if err != nil {
		return nil, err
	}
	reqQP := req.Raw().URL.Query()
	reqQP.Set("comp", "blocklist")
	if options != nil && options.Timeout != nil {
		reqQP.Set("timeout", strconv.FormatInt(int64(*options.Timeout), 10))
	}
	req.Raw().URL.RawQuery = strings.ReplaceAll(reqQP.Encode(), "+", "%20")
	req.Raw().Header["Accept"] = []string{"application/xml"}
	if options != nil && options.TransactionalContentMD5 != nil {
		req.Raw().Header["Content-MD5"] = []string{base64.StdEncoding.EncodeToString(options.TransactionalContentMD5)}
	}
	if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
		req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
	}
	if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
		req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
	}
	if modifiedAccessConditions != nil && modifiedAccessConditions.IfNoneMatch != nil {
		req.Raw().Header["If-None-Match"] = []string{string(*modifiedAccessConditions.IfNoneMatch)}
	}
	if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
		req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
	}
	if options != nil && options.Tier != nil {
		req.Raw().Header["x-ms-access-tier"] = []string{string(*options.Tier)}
	}
	if blobHTTPHeaders != nil && blobHTTPHeaders.BlobCacheControl != nil {
		req.Raw().Header["x-ms-blob-cache-control"] = []string{*blobHTTPHeaders.BlobCacheControl}
	}
	if blobHTTPHeaders != nil && blobHTTPHeaders.BlobContentDisposition != nil {
		req.Raw().Header["x-ms-blob-content-disposition"] = []string{*blobHTTPHeaders.BlobContentDisposition}
	}
	if blobHTTPHeaders != nil && blobHTTPHeaders.BlobContentEncoding != nil {
		req.Raw().Header["x-ms-blob-content-encoding"] = []string{*blobHTTPHeaders.BlobContentEncoding}
	}
	if blobHTTPHeaders != nil && blobHTTPHeaders.BlobContentLanguage != nil {
		req.Raw().Header["x-ms-blob-content-language"] = []string{*blobHTTPHeaders.BlobContentLanguage}
	}
	if blobHTTPHeaders != nil && blobHTTPHeaders.BlobContentMD5 != nil {
		req.Raw().Header["x-ms-blob-content-md5"] = []string{base64.StdEncoding.EncodeToString(blobHTTPHeaders.BlobContentMD5)}
	}
	if blobHTTPHeaders != nil && blobHTTPHeaders.BlobContentType != nil {
		req.Raw().Header["x-ms-blob-content-type"] = []string{*blobHTTPHeaders.BlobContentType}
	}
	if options != nil && options.RequestID != nil {
		req.Raw().Header["x-ms-client-request-id"] = []string{*options.RequestID}
	}
	if options != nil && options.TransactionalContentCRC64 != nil {
		req.Raw().Header["x-ms-content-crc64"] = []string{base64.StdEncoding.EncodeToString(options.TransactionalContentCRC64)}
	}
	if cpkInfo != nil && cpkInfo.EncryptionAlgorithm != nil {
		req.Raw().Header["x-ms-encryption-algorithm"] = []string{string(*cpkInfo.EncryptionAlgorithm)}
	}
	if cpkInfo != nil && cpkInfo.EncryptionKey != nil {
		req.Raw().Header["x-ms-encryption-key"] = []string{*cpkInfo.EncryptionKey}
	}
	if cpkInfo != nil && cpkInfo.EncryptionKeySHA256 != nil {
		req.Raw().Header["x-ms-encryption-key-sha256"] = []string{*cpkInfo.EncryptionKeySHA256}
	}
	if cpkScopeInfo != nil && cpkScopeInfo.EncryptionScope != nil {
		req.Raw().Header["x-ms-encryption-scope"] = []string{*cpkScopeInfo.EncryptionScope}
	}
	if modifiedAccessConditions != nil && modifiedAccessConditions.IfTags != nil {
		req.Raw().Header["x-ms-if-tags"] = []string{*modifiedAccessConditions.IfTags}
	}
	if options != nil && options.ImmutabilityPolicyMode != nil {
		req.Raw().Header["x-ms-immutability-policy-mode"] = []string{string(*options.ImmutabilityPolicyMode)}
	}
	if options != nil && options.ImmutabilityPolicyExpiry != nil {
		req.Raw().Header["x-ms-immutability-policy-until-date"] = []string{(*options.ImmutabilityPolicyExpiry).In(gmt).Format(time.RFC1123)}
	}
	if leaseAccessConditions != nil && leaseAccessConditions.LeaseID != nil {
		req.Raw().Header["x-ms-lease-id"] = []string{*leaseAccessConditions.LeaseID}
	}
	if options != nil && options.LegalHold != nil {
		req.Raw().Header["x-ms-legal-hold"] = []string{strconv.FormatBool(*options.LegalHold)}
	}
	if options != nil && options.Metadata != nil {
		for k, v := range options.Metadata {
			if v != nil {
				req.Raw().Header["x-ms-meta-"+k] = []string{*v}
			}
		}
	}
	if options != nil && options.BlobTagsString != nil {
		req.Raw().Header["x-ms-tags"] = []string{*options.BlobTagsString}
	}
	req.Raw().Header["x-ms-version"] = []string{client.version}
	if err := runtime.MarshalAsXML(req, blocks); err != nil {
		return nil, err
	}
	return req, nil
}

// commitBlockListHandleResponse handles the CommitBlockList response.
func (client *BlockBlobClient) commitBlockListHandleResponse(resp *http.Response) (BlockBlobClientCommitBlockListResponse, error) {
	result := BlockBlobClientCommitBlockListResponse{}
	if val := resp.Header.Get("x-ms-client-request-id"); val != "" {
		result.ClientRequestID = &val
	}
	if val := resp.Header.Get("x-ms-content-crc64"); val != "" {
		contentCRC64, err := base64.StdEncoding.DecodeString(val)
		if err != nil {
			return BlockBlobClientCommitBlockListResponse{}, err
		}
		result.ContentCRC64 = contentCRC64
	}
	if val := resp.Header.Get("Content-MD5"); val != "" {
		contentMD5, err := base64.StdEncoding.DecodeString(val)
		if err != nil {
			return BlockBlobClientCommitBlockListResponse{}, err
		}
		result.ContentMD5 = contentMD5
	}
	if val := resp.Header.Get("Date"); val != "" {
		date, err := time.Parse(time.RFC1123, val)
		if err != nil {
			return BlockBlobClientCommitBlockListResponse{}, err
		}
		result.Date = &date
	}
	if val := resp.Header.Get("ETag"); val != "" {
		result.ETag = (*azcore.ETag)(&val)
	}
	if val := resp.Header.Get("x-ms-encryption-key-sha256"); val != "" {
		result.EncryptionKeySHA256 = &val
	}
	if val := resp.Header.Get("x-ms-encryption-scope"); val != "" {
		result.EncryptionScope = &val
	}
	if val := resp.Header.Get("x-ms-request-server-encrypted"); val != "" {
		isServerEncrypted, err := strconv.ParseBool(val)
		if err != nil {
			return BlockBlobClientCommitBlockListResponse{}, err
		}
		result.IsServerEncrypted = &isServerEncrypted
	}
	if val := resp.Header.Get("Last-Modified"); val != "" {
		lastModified, err := time.Parse(time.RFC1123, val)
		if err != nil {
			return BlockBlobClientCommitBlockListResponse{}, err
		}
		result.LastModified = &lastModified
	}
	if val := resp.Header.Get("x-ms-request-id"); val != "" {
		result.RequestID = &val
	}
	if val := resp.Header.Get("x-ms-version"); val != "" {
		result.Version = &val
	}
	if val := resp.Header.Get("x-ms-version-id"); val != "" {
		result.VersionID = &val
	}
	return result, nil
}

// GetBlockList - The Get Block List operation retrieves the list of blocks that have been uploaded as part of a block blob
// If the operation fails it returns an *azcore.ResponseError type.
//   - listType - Specifies whether to return the list of committed blocks, the list of uncommitted blocks, or both lists together.
//   - options - BlockBlobClientGetBlockListOptions contains the optional parameters for the BlockBlobClient.GetBlockList method.
//   - LeaseAccessConditions - LeaseAccessConditions contains a group of parameters for the ContainerClient.GetProperties method.
//   - ModifiedAccessConditions - ModifiedAccessConditions contains a group of parameters for the ContainerClient.Delete method.
func (client *BlockBlobClient) GetBlockList(ctx context.Context, listType BlockListType, options *BlockBlobClientGetBlockListOptions, leaseAccessConditions *LeaseAccessConditions, modifiedAccessConditions *ModifiedAccessConditions) (BlockBlobClientGetBlockListResponse, error) {
	var err error
	req, err := client.getBlockListCreateRequest(ctx, listType, options, leaseAccessConditions, modifiedAccessConditions)
	if err != nil {
		return BlockBlobClientGetBlockListResponse{}, err
	}
	httpResp, err := client.internal.Pipeline().Do(req)
	if err != nil {
		return BlockBlobClientGetBlockListResponse{}, err
	}
	if !runtime.HasStatusCode(httpResp, http.StatusOK) {
		err = runtime.NewResponseError(httpResp)
		return BlockBlobClientGetBlockListResponse{}, err
	}
	resp, err := client.getBlockListHandleResponse(httpResp)
	return resp, err
}

// getBlockListCreateRequest creates the GetBlockList request.
func (client *BlockBlobClient) getBlockListCreateRequest(ctx context.Context, listType BlockListType, options *BlockBlobClientGetBlockListOptions, leaseAccessConditions *LeaseAccessConditions, modifiedAccessConditions *ModifiedAccessConditions) (*policy.Request, error) {
	req, err := runtime.NewRequest(ctx, http.MethodGet, client.endpoint)
	if err != nil {
		return nil, err
	}
	reqQP := req.Raw().URL.Query()
	reqQP.Set("blocklisttype", string(listType))
	reqQP.Set("comp", "blocklist")
	if options != nil && options.Snapshot != nil {
		reqQP.Set("snapshot", *options.Snapshot)
	}
	if options != nil && options.Timeout != nil {
		reqQP.Set("timeout", strconv.FormatInt(int64(*options.Timeout), 10))
	}
	req.Raw().URL.RawQuery = strings.ReplaceAll(reqQP.Encode(), "+", "%20")
	req.Raw().Header["Accept"] = []string{"application/xml"}
	if options != nil && options.RequestID != nil {
		req.Raw().Header["x-ms-client-request-id"] = []string{*options.RequestID}
	}
	if modifiedAccessConditions != nil && modifiedAccessConditions.IfTags != nil {
		req.Raw().Header["x-ms-if-tags"] = []string{*modifiedAccessConditions.IfTags}
	}
	if leaseAccessConditions != nil && leaseAccessConditions.LeaseID != nil {
		req.Raw().Header["x-ms-lease-id"] = []string{*leaseAccessConditions.LeaseID}
	}
	req.Raw().Header["x-ms-version"] = []string{client.version}
	return req, nil
}

// getBlockListHandleResponse handles the GetBlockList response.
func (client *BlockBlobClient) getBlockListHandleResponse(resp *http.Response) (BlockBlobClientGetBlockListResponse, error) {
	result := BlockBlobClientGetBlockListResponse{}
	if val := resp.Header.Get("x-ms-blob-content-length"); val != "" {
		blobContentLength, err := strconv.ParseInt(val, 10, 64)
		if err != nil {
			return BlockBlobClientGetBlockListResponse{}, err
		}
		result.BlobContentLength = &blobContentLength
	}
	if val := resp.Header.Get("x-ms-client-request-id"); val != "" {
		result.ClientRequestID = &val
	}
	if val := resp.Header.Get("Content-Type"); val != "" {
		result.ContentType = &val
	}
	if val := resp.Header.Get("Date"); val != "" {
		date, err := time.Parse(time.RFC1123, val)
		if err != nil {
			return BlockBlobClientGetBlockListResponse{}, err
		}
		result.Date = &date
	}
	if val := resp.Header.Get("ETag"); val != "" {
		result.ETag = (*azcore.ETag)(&val)
	}
	if val := resp.Header.Get("Last-Modified"); val != "" {
		lastModified, err := time.Parse(time.RFC1123, val)
		if err != nil {
			return BlockBlobClientGetBlockListResponse{}, err
		}
		result.LastModified = &lastModified
	}
	if val := resp.Header.Get("x-ms-request-id"); val != "" {
		result.RequestID = &val
	}
	if val := resp.Header.Get("x-ms-version"); val != "" {
		result.Version = &val
	}
	if err := runtime.UnmarshalAsXML(resp, &result.BlockList); err != nil {
		return BlockBlobClientGetBlockListResponse{}, err
	}
	return result, nil
}

// PutBlobFromURL - The Put Blob from URL operation creates a new Block Blob where the contents of the blob are read from
// a given URL. This API is supported beginning with the 2020-04-08 version. Partial updates are not
// supported with Put Blob from URL; the content of an existing blob is overwritten with the content of the new blob. To perform
// partial updates to a block blob’s contents using a source URL, use the Put
// Block from URL API in conjunction with Put Block List.
// If the operation fails it returns an *azcore.ResponseError type.
//   - contentLength - The length of the request.
//   - copySource - Specifies the name of the source page blob snapshot. This value is a URL of up to 2 KB in length that specifies
//     a page blob snapshot. The value should be URL-encoded as it would appear in a request
//     URI. The source blob must either be public or must be authenticated via a shared access signature.
//   - options - BlockBlobClientPutBlobFromURLOptions contains the optional parameters for the BlockBlobClient.PutBlobFromURL
//     method.
//   - BlobHTTPHeaders - BlobHTTPHeaders contains a group of parameters for the BlobClient.SetHTTPHeaders method.
//   - LeaseAccessConditions - LeaseAccessConditions contains a group of parameters for the ContainerClient.GetProperties method.
//   - CPKInfo - CPKInfo contains a group of parameters for the BlobClient.Download method.
//   - CPKScopeInfo - CPKScopeInfo contains a group of parameters for the BlobClient.SetMetadata method.
//   - ModifiedAccessConditions - ModifiedAccessConditions contains a group of parameters for the ContainerClient.Delete method.
//   - SourceModifiedAccessConditions - SourceModifiedAccessConditions contains a group of parameters for the BlobClient.StartCopyFromURL
//     method.
//   - SourceCPKInfo - SourceCPKInfo contains a group of parameters for the PageBlobClient.UploadPagesFromURL method.
func (client *BlockBlobClient) PutBlobFromURL(ctx context.Context, contentLength int64, copySource string, options *BlockBlobClientPutBlobFromURLOptions, blobHTTPHeaders *BlobHTTPHeaders, leaseAccessConditions *LeaseAccessConditions, cpkInfo *CPKInfo, cpkScopeInfo *CPKScopeInfo, modifiedAccessConditions *ModifiedAccessConditions, sourceModifiedAccessConditions *SourceModifiedAccessConditions, sourceCPKInfo *SourceCPKInfo) (BlockBlobClientPutBlobFromURLResponse, error) {
	var err error
	req, err := client.putBlobFromURLCreateRequest(ctx, contentLength, copySource, options, blobHTTPHeaders, leaseAccessConditions, cpkInfo, cpkScopeInfo, modifiedAccessConditions, sourceModifiedAccessConditions, sourceCPKInfo)
	if err != nil {
		return BlockBlobClientPutBlobFromURLResponse{}, err
	}
	httpResp, err := client.internal.Pipeline().Do(req)
	if err != nil {
		return BlockBlobClientPutBlobFromURLResponse{}, err
	}
	if !runtime.HasStatusCode(httpResp, http.StatusCreated) {
		err = runtime.NewResponseError(httpResp)
		return BlockBlobClientPutBlobFromURLResponse{}, err
	}
	resp, err := client.putBlobFromURLHandleResponse(httpResp)
	return resp, err
}

// putBlobFromURLCreateRequest creates the PutBlobFromURL request.
func (client *BlockBlobClient) putBlobFromURLCreateRequest(ctx context.Context, contentLength int64, copySource string, options *BlockBlobClientPutBlobFromURLOptions, blobHTTPHeaders *BlobHTTPHeaders, leaseAccessConditions *LeaseAccessConditions, cpkInfo *CPKInfo, cpkScopeInfo *CPKScopeInfo, modifiedAccessConditions *ModifiedAccessConditions, sourceModifiedAccessConditions *SourceModifiedAccessConditions, sourceCPKInfo *SourceCPKInfo) (*policy.Request, error) {
	req, err := runtime.NewRequest(ctx, http.MethodPut, client.endpoint)
	if err != nil {
		return nil, err
	}
	reqQP := req.Raw().URL.Query()
	if options != nil && options.Timeout != nil {
		reqQP.Set("timeout", strconv.FormatInt(int64(*options.Timeout), 10))
	}
	req.Raw().URL.RawQuery = strings.ReplaceAll(reqQP.Encode(), "+", "%20")
	req.Raw().Header["Accept"] = []string{"application/xml"}
	req.Raw().Header["Content-Length"] = []string{strconv.FormatInt(contentLength, 10)}
	if options != nil && options.TransactionalContentMD5 != nil {
		req.Raw().Header["Content-MD5"] = []string{base64.StdEncoding.EncodeToString(options.TransactionalContentMD5)}
	}
	if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
		req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
	}
	if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
		req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
	}
	if modifiedAccessConditions != nil && modifiedAccessConditions.IfNoneMatch != nil {
		req.Raw().Header["If-None-Match"] = []string{string(*modifiedAccessConditions.IfNoneMatch)}
	}
	if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
		req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
	}
	if options != nil && options.Tier != nil {
		req.Raw().Header["x-ms-access-tier"] = []string{string(*options.Tier)}
	}
	if blobHTTPHeaders != nil && blobHTTPHeaders.BlobCacheControl != nil {
		req.Raw().Header["x-ms-blob-cache-control"] = []string{*blobHTTPHeaders.BlobCacheControl}
	}
	if blobHTTPHeaders != nil && blobHTTPHeaders.BlobContentDisposition != nil {
		req.Raw().Header["x-ms-blob-content-disposition"] = []string{*blobHTTPHeaders.BlobContentDisposition}
	}
	if blobHTTPHeaders != nil && blobHTTPHeaders.BlobContentEncoding != nil {
		req.Raw().Header["x-ms-blob-content-encoding"] = []string{*blobHTTPHeaders.BlobContentEncoding}
	}
	if blobHTTPHeaders != nil && blobHTTPHeaders.BlobContentLanguage != nil {
		req.Raw().Header["x-ms-blob-content-language"] = []string{*blobHTTPHeaders.BlobContentLanguage}
	}
	if blobHTTPHeaders != nil && blobHTTPHeaders.BlobContentMD5 != nil {
		req.Raw().Header["x-ms-blob-content-md5"] = []string{base64.StdEncoding.EncodeToString(blobHTTPHeaders.BlobContentMD5)}
	}
	if blobHTTPHeaders != nil && blobHTTPHeaders.BlobContentType != nil {
		req.Raw().Header["x-ms-blob-content-type"] = []string{*blobHTTPHeaders.BlobContentType}
	}
	req.Raw().Header["x-ms-blob-type"] = []string{"BlockBlob"}
	if options != nil && options.RequestID != nil {
		req.Raw().Header["x-ms-client-request-id"] = []string{*options.RequestID}
	}
	req.Raw().Header["x-ms-copy-source"] = []string{copySource}
	if options != nil && options.CopySourceAuthorization != nil {
		req.Raw().Header["x-ms-copy-source-authorization"] = []string{*options.CopySourceAuthorization}
	}
	if options != nil && options.CopySourceBlobProperties != nil {
		req.Raw().Header["x-ms-copy-source-blob-properties"] = []string{strconv.FormatBool(*options.CopySourceBlobProperties)}
	}
	if options != nil && options.CopySourceTags != nil {
		req.Raw().Header["x-ms-copy-source-tag-option"] = []string{string(*options.CopySourceTags)}
	}
	if cpkInfo != nil && cpkInfo.EncryptionAlgorithm != nil {
		req.Raw().Header["x-ms-encryption-algorithm"] = []string{string(*cpkInfo.EncryptionAlgorithm)}
	}
	if cpkInfo != nil && cpkInfo.EncryptionKey != nil {
		req.Raw().Header["x-ms-encryption-key"] = []string{*cpkInfo.EncryptionKey}
	}
	if cpkInfo != nil && cpkInfo.EncryptionKeySHA256 != nil {
		req.Raw().Header["x-ms-encryption-key-sha256"] = []string{*cpkInfo.EncryptionKeySHA256}
	}
	if cpkScopeInfo != nil && cpkScopeInfo.EncryptionScope != nil {
		req.Raw().Header["x-ms-encryption-scope"] = []string{*cpkScopeInfo.EncryptionScope}
	}
	if options != nil && options.FileRequestIntent != nil {
		req.Raw().Header["x-ms-file-request-intent"] = []string{string(*options.FileRequestIntent)}
	}
	if modifiedAccessConditions != nil && modifiedAccessConditions.IfTags != nil {
		req.Raw().Header["x-ms-if-tags"] = []string{*modifiedAccessConditions.IfTags}
	}
	if leaseAccessConditions != nil && leaseAccessConditions.LeaseID != nil {
		req.Raw().Header["x-ms-lease-id"] = []string{*leaseAccessConditions.LeaseID}
	}
	if options != nil && options.Metadata != nil {
		for k, v := range options.Metadata {
			if v != nil {
				req.Raw().Header["x-ms-meta-"+k] = []string{*v}
			}
		}
	}
	if options != nil && options.SourceContentMD5 != nil {
		req.Raw().Header["x-ms-source-content-md5"] = []string{base64.StdEncoding.EncodeToString(options.SourceContentMD5)}
	}
	if sourceCPKInfo != nil && sourceCPKInfo.SourceEncryptionAlgorithm != nil {
		req.Raw().Header["x-ms-source-encryption-algorithm"] = []string{string(*sourceCPKInfo.SourceEncryptionAlgorithm)}
	}
	if sourceCPKInfo != nil && sourceCPKInfo.SourceEncryptionKey != nil {
		req.Raw().Header["x-ms-source-encryption-key"] = []string{*sourceCPKInfo.SourceEncryptionKey}
	}
	if sourceCPKInfo != nil && sourceCPKInfo.SourceEncryptionKeySHA256 != nil {
		req.Raw().Header["x-ms-source-encryption-key-sha256"] = []string{*sourceCPKInfo.SourceEncryptionKeySHA256}
	}
	if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfMatch != nil {
		req.Raw().Header["x-ms-source-if-match"] = []string{string(*sourceModifiedAccessConditions.SourceIfMatch)}
	}
	if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfModifiedSince != nil {
		req.Raw().Header["x-ms-source-if-modified-since"] = []string{(*sourceModifiedAccessConditions.SourceIfModifiedSince).In(gmt).Format(time.RFC1123)}
	}
	if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfNoneMatch != nil {
		req.Raw().Header["x-ms-source-if-none-match"] = []string{string(*sourceModifiedAccessConditions.SourceIfNoneMatch)}
	}
	if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfTags != nil {
		req.Raw().Header["x-ms-source-if-tags"] = []string{*sourceModifiedAccessConditions.SourceIfTags}
	}
	if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfUnmodifiedSince != nil {
		req.Raw().Header["x-ms-source-if-unmodified-since"] = []string{(*sourceModifiedAccessConditions.SourceIfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
	}
	if options != nil && options.BlobTagsString != nil {
		req.Raw().Header["x-ms-tags"] = []string{*options.BlobTagsString}
	}
	req.Raw().Header["x-ms-version"] = []string{client.version}
	return req, nil
}

// putBlobFromURLHandleResponse handles the PutBlobFromURL response.
func (client *BlockBlobClient) putBlobFromURLHandleResponse(resp *http.Response) (BlockBlobClientPutBlobFromURLResponse, error) {
	result := BlockBlobClientPutBlobFromURLResponse{}
	if val := resp.Header.Get("x-ms-client-request-id"); val != "" {
		result.ClientRequestID = &val
	}
	if val := resp.Header.Get("x-ms-content-crc64"); val != "" {
		contentCRC64, err := base64.StdEncoding.DecodeString(val)
		if err != nil {
			return BlockBlobClientPutBlobFromURLResponse{}, err
		}
		result.ContentCRC64 = contentCRC64
	}
	if val := resp.Header.Get("Content-MD5"); val != "" {
		contentMD5, err := base64.StdEncoding.DecodeString(val)
		if err != nil {
			return BlockBlobClientPutBlobFromURLResponse{}, err
		}
		result.ContentMD5 = contentMD5
	}
	if val := resp.Header.Get("Date"); val != "" {
		date, err := time.Parse(time.RFC1123, val)
		if err != nil {
			return BlockBlobClientPutBlobFromURLResponse{}, err
		}
		result.Date = &date
	}
	if val := resp.Header.Get("ETag"); val != "" {
		result.ETag = (*azcore.ETag)(&val)
	}
	if val := resp.Header.Get("x-ms-encryption-key-sha256"); val != "" {
		result.EncryptionKeySHA256 = &val
	}
	if val := resp.Header.Get("x-ms-encryption-scope"); val != "" {
		result.EncryptionScope = &val
	}
	if val := resp.Header.Get("x-ms-request-server-encrypted"); val != "" {
		isServerEncrypted, err := strconv.ParseBool(val)
		if err != nil {
			return BlockBlobClientPutBlobFromURLResponse{}, err
		}
		result.IsServerEncrypted = &isServerEncrypted
	}
	if val := resp.Header.Get("Last-Modified"); val != "" {
		lastModified, err := time.Parse(time.RFC1123, val)
		if err != nil {
			return BlockBlobClientPutBlobFromURLResponse{}, err
		}
		result.LastModified = &lastModified
	}
	if val := resp.Header.Get("x-ms-request-id"); val != "" {
		result.RequestID = &val
	}
	if val := resp.Header.Get("x-ms-version"); val != "" {
		result.Version = &val
	}
	if val := resp.Header.Get("x-ms-version-id"); val != "" {
		result.VersionID = &val
	}
	return result, nil
}

// StageBlock - The Stage Block operation creates a new block to be committed as part of a blob
// If the operation fails it returns an *azcore.ResponseError type.
//   - blockID - A valid Base64 string value that identifies the block. Prior to encoding, the string must be less than or equal
//     to 64 bytes in size. For a given blob, the length of the value specified for the blockid
//     parameter must be the same size for each block.
//   - contentLength - The length of the request.
//   - body - Initial data
//   - options - BlockBlobClientStageBlockOptions contains the optional parameters for the BlockBlobClient.StageBlock method.
//   - LeaseAccessConditions - LeaseAccessConditions contains a group of parameters for the ContainerClient.GetProperties method.
//   - CPKInfo - CPKInfo contains a group of parameters for the BlobClient.Download method.
//   - CPKScopeInfo - CPKScopeInfo contains a group of parameters for the BlobClient.SetMetadata method.
func (client *BlockBlobClient) StageBlock(ctx context.Context, blockID string, contentLength int64, body io.ReadSeekCloser, options *BlockBlobClientStageBlockOptions, leaseAccessConditions *LeaseAccessConditions, cpkInfo *CPKInfo, cpkScopeInfo *CPKScopeInfo) (BlockBlobClientStageBlockResponse, error) {
	var err error
	req, err := client.stageBlockCreateRequest(ctx, blockID, contentLength, body, options, leaseAccessConditions, cpkInfo, cpkScopeInfo)
	if err != nil {
		return BlockBlobClientStageBlockResponse{}, err
	}
	httpResp, err := client.internal.Pipeline().Do(req)
	if err != nil {
		return BlockBlobClientStageBlockResponse{}, err
	}
	if !runtime.HasStatusCode(httpResp, http.StatusCreated) {
		err = runtime.NewResponseError(httpResp)
		return BlockBlobClientStageBlockResponse{}, err
	}
	resp, err := client.stageBlockHandleResponse(httpResp)
	return resp, err
}

// stageBlockCreateRequest creates the StageBlock request.
func (client *BlockBlobClient) stageBlockCreateRequest(ctx context.Context, blockID string, contentLength int64, body io.ReadSeekCloser, options *BlockBlobClientStageBlockOptions, leaseAccessConditions *LeaseAccessConditions, cpkInfo *CPKInfo, cpkScopeInfo *CPKScopeInfo) (*policy.Request, error) {
	req, err := runtime.NewRequest(ctx, http.MethodPut, client.endpoint)
	if err != nil {
		return nil, err
	}
	reqQP := req.Raw().URL.Query()
	reqQP.Set("blockid", blockID)
	reqQP.Set("comp", "block")
	if options != nil && options.Timeout != nil {
		reqQP.Set("timeout", strconv.FormatInt(int64(*options.Timeout), 10))
	}
	req.Raw().URL.RawQuery = strings.ReplaceAll(reqQP.Encode(), "+", "%20")
	req.Raw().Header["Accept"] = []string{"application/xml"}
	req.Raw().Header["Content-Length"] = []string{strconv.FormatInt(contentLength, 10)}
	if options != nil && options.TransactionalContentMD5 != nil {
		req.Raw().Header["Content-MD5"] = []string{base64.StdEncoding.EncodeToString(options.TransactionalContentMD5)}
	}
	if options != nil && options.RequestID != nil {
		req.Raw().Header["x-ms-client-request-id"] = []string{*options.RequestID}
	}
	if options != nil && options.TransactionalContentCRC64 != nil {
		req.Raw().Header["x-ms-content-crc64"] = []string{base64.StdEncoding.EncodeToString(options.TransactionalContentCRC64)}
	}
	if cpkInfo != nil && cpkInfo.EncryptionAlgorithm != nil {
		req.Raw().Header["x-ms-encryption-algorithm"] = []string{string(*cpkInfo.EncryptionAlgorithm)}
	}
	if cpkInfo != nil && cpkInfo.EncryptionKey != nil {
		req.Raw().Header["x-ms-encryption-key"] = []string{*cpkInfo.EncryptionKey}
	}
	if cpkInfo != nil && cpkInfo.EncryptionKeySHA256 != nil {
		req.Raw().Header["x-ms-encryption-key-sha256"] = []string{*cpkInfo.EncryptionKeySHA256}
	}
	if cpkScopeInfo != nil && cpkScopeInfo.EncryptionScope != nil {
		req.Raw().Header["x-ms-encryption-scope"] = []string{*cpkScopeInfo.EncryptionScope}
	}
	if leaseAccessConditions != nil && leaseAccessConditions.LeaseID != nil {
		req.Raw().Header["x-ms-lease-id"] = []string{*leaseAccessConditions.LeaseID}
	}
	if options != nil && options.StructuredBodyType != nil {
		req.Raw().Header["x-ms-structured-body"] = []string{*options.StructuredBodyType}
	}
	if options != nil && options.StructuredContentLength != nil {
		req.Raw().Header["x-ms-structured-content-length"] = []string{strconv.FormatInt(*options.StructuredContentLength, 10)}
	}
	req.Raw().Header["x-ms-version"] = []string{client.version}
	if err := req.SetBody(body, "application/octet-stream"); err != nil {
		return nil, err
	}
	return req, nil
}

// stageBlockHandleResponse handles the StageBlock response.
func (client *BlockBlobClient) stageBlockHandleResponse(resp *http.Response) (BlockBlobClientStageBlockResponse, error) {
	result := BlockBlobClientStageBlockResponse{}
	if val := resp.Header.Get("x-ms-client-request-id"); val != "" {
		result.ClientRequestID = &val
	}
	if val := resp.Header.Get("x-ms-content-crc64"); val != "" {
		contentCRC64, err := base64.StdEncoding.DecodeString(val)
		if err != nil {
			return BlockBlobClientStageBlockResponse{}, err
		}
		result.ContentCRC64 = contentCRC64
	}
	if val := resp.Header.Get("Content-MD5"); val != "" {
		contentMD5, err := base64.StdEncoding.DecodeString(val)
		if err != nil {
			return BlockBlobClientStageBlockResponse{}, err
		}
		result.ContentMD5 = contentMD5
	}
	if val := resp.Header.Get("Date"); val != "" {
		date, err := time.Parse(time.RFC1123, val)
		if err != nil {
			return BlockBlobClientStageBlockResponse{}, err
		}
		result.Date = &date
	}
	if val := resp.Header.Get("x-ms-encryption-key-sha256"); val != "" {
		result.EncryptionKeySHA256 = &val
	}
	if val := resp.Header.Get("x-ms-encryption-scope"); val != "" {
		result.EncryptionScope = &val
	}
	if val := resp.Header.Get("x-ms-request-server-encrypted"); val != "" {
		isServerEncrypted, err := strconv.ParseBool(val)
		if err != nil {
			return BlockBlobClientStageBlockResponse{}, err
		}
		result.IsServerEncrypted = &isServerEncrypted
	}
	if val := resp.Header.Get("x-ms-request-id"); val != "" {
		result.RequestID = &val
	}
	if val := resp.Header.Get("x-ms-structured-body"); val != "" {
		result.StructuredBodyType = &val
	}
	if val := resp.Header.Get("x-ms-version"); val != "" {
		result.Version = &val
	}
	return result, nil
}

// StageBlockFromURL - The Stage Block operation creates a new block to be committed as part of a blob where the contents
// are read from a URL.
// If the operation fails it returns an *azcore.ResponseError type.
//   - blockID - A valid Base64 string value that identifies the block. Prior to encoding, the string must be less than or equal
//     to 64 bytes in size. For a given blob, the length of the value specified for the blockid
//     parameter must be the same size for each block.
//   - contentLength - The length of the request.
//   - sourceURL - Specify a URL to the copy source.
//   - options - BlockBlobClientStageBlockFromURLOptions contains the optional parameters for the BlockBlobClient.StageBlockFromURL
//     method.
//   - CPKInfo - CPKInfo contains a group of parameters for the BlobClient.Download method.
//   - CPKScopeInfo - CPKScopeInfo contains a group of parameters for the BlobClient.SetMetadata method.
//   - LeaseAccessConditions - LeaseAccessConditions contains a group of parameters for the ContainerClient.GetProperties method.
//   - SourceModifiedAccessConditions - SourceModifiedAccessConditions contains a group of parameters for the BlobClient.StartCopyFromURL
//     method.
//   - SourceCPKInfo - SourceCPKInfo contains a group of parameters for the PageBlobClient.UploadPagesFromURL method.
func (client *BlockBlobClient) StageBlockFromURL(ctx context.Context, blockID string, contentLength int64, sourceURL string, options *BlockBlobClientStageBlockFromURLOptions, cpkInfo *CPKInfo, cpkScopeInfo *CPKScopeInfo, leaseAccessConditions *LeaseAccessConditions, sourceModifiedAccessConditions *SourceModifiedAccessConditions, sourceCPKInfo *SourceCPKInfo) (BlockBlobClientStageBlockFromURLResponse, error) {
	var err error
	req, err := client.stageBlockFromURLCreateRequest(ctx, blockID, contentLength, sourceURL, options, cpkInfo, cpkScopeInfo, leaseAccessConditions, sourceModifiedAccessConditions, sourceCPKInfo)
	if err != nil {
		return BlockBlobClientStageBlockFromURLResponse{}, err
	}
	httpResp, err := client.internal.Pipeline().Do(req)
	if err != nil {
		return BlockBlobClientStageBlockFromURLResponse{}, err
	}
	if !runtime.HasStatusCode(httpResp, http.StatusCreated) {
		err = runtime.NewResponseError(httpResp)
		return BlockBlobClientStageBlockFromURLResponse{}, err
	}
	resp, err := client.stageBlockFromURLHandleResponse(httpResp)
	return resp, err
}

// stageBlockFromURLCreateRequest creates the StageBlockFromURL request.
func (client *BlockBlobClient) stageBlockFromURLCreateRequest(ctx context.Context, blockID string, contentLength int64, sourceURL string, options *BlockBlobClientStageBlockFromURLOptions, cpkInfo *CPKInfo, cpkScopeInfo *CPKScopeInfo, leaseAccessConditions *LeaseAccessConditions, sourceModifiedAccessConditions *SourceModifiedAccessConditions, sourceCPKInfo *SourceCPKInfo) (*policy.Request, error) {
	req, err := runtime.NewRequest(ctx, http.MethodPut, client.endpoint)
	if err != nil {
		return nil, err
	}
	reqQP := req.Raw().URL.Query()
	reqQP.Set("blockid", blockID)
	reqQP.Set("comp", "block")
	if options != nil && options.Timeout != nil {
		reqQP.Set("timeout", strconv.FormatInt(int64(*options.Timeout), 10))
	}
	req.Raw().URL.RawQuery = strings.ReplaceAll(reqQP.Encode(), "+", "%20")
	req.Raw().Header["Accept"] = []string{"application/xml"}
	req.Raw().Header["Content-Length"] = []string{strconv.FormatInt(contentLength, 10)}
	if options != nil && options.RequestID != nil {
		req.Raw().Header["x-ms-client-request-id"] = []string{*options.RequestID}
	}
	req.Raw().Header["x-ms-copy-source"] = []string{sourceURL}
	if options != nil && options.CopySourceAuthorization != nil {
		req.Raw().Header["x-ms-copy-source-authorization"] = []string{*options.CopySourceAuthorization}
	}
	if cpkInfo != nil && cpkInfo.EncryptionAlgorithm != nil {
		req.Raw().Header["x-ms-encryption-algorithm"] = []string{string(*cpkInfo.EncryptionAlgorithm)}
	}
	if cpkInfo != nil && cpkInfo.EncryptionKey != nil {
		req.Raw().Header["x-ms-encryption-key"] = []string{*cpkInfo.EncryptionKey}
	}
	if cpkInfo != nil && cpkInfo.EncryptionKeySHA256 != nil {
		req.Raw().Header["x-ms-encryption-key-sha256"] = []string{*cpkInfo.EncryptionKeySHA256}
	}
	if cpkScopeInfo != nil && cpkScopeInfo.EncryptionScope != nil {
		req.Raw().Header["x-ms-encryption-scope"] = []string{*cpkScopeInfo.EncryptionScope}
	}
	if options != nil && options.FileRequestIntent != nil {
		req.Raw().Header["x-ms-file-request-intent"] = []string{string(*options.FileRequestIntent)}
	}
	if leaseAccessConditions != nil && leaseAccessConditions.LeaseID != nil {
		req.Raw().Header["x-ms-lease-id"] = []string{*leaseAccessConditions.LeaseID}
	}
	if options != nil && options.SourceContentcrc64 != nil {
		req.Raw().Header["x-ms-source-content-crc64"] = []string{base64.StdEncoding.EncodeToString(options.SourceContentcrc64)}
	}
	if options != nil && options.SourceContentMD5 != nil {
		req.Raw().Header["x-ms-source-content-md5"] = []string{base64.StdEncoding.EncodeToString(options.SourceContentMD5)}
	}
	if sourceCPKInfo != nil && sourceCPKInfo.SourceEncryptionAlgorithm != nil {
		req.Raw().Header["x-ms-source-encryption-algorithm"] = []string{string(*sourceCPKInfo.SourceEncryptionAlgorithm)}
	}
	if sourceCPKInfo != nil && sourceCPKInfo.SourceEncryptionKey != nil {
		req.Raw().Header["x-ms-source-encryption-key"] = []string{*sourceCPKInfo.SourceEncryptionKey}
	}
	if sourceCPKInfo != nil && sourceCPKInfo.SourceEncryptionKeySHA256 != nil {
		req.Raw().Header["x-ms-source-encryption-key-sha256"] = []string{*sourceCPKInfo.SourceEncryptionKeySHA256}
	}
	if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfMatch != nil {
		req.Raw().Header["x-ms-source-if-match"] = []string{string(*sourceModifiedAccessConditions.SourceIfMatch)}
	}
	if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfModifiedSince != nil {
		req.Raw().Header["x-ms-source-if-modified-since"] = []string{(*sourceModifiedAccessConditions.SourceIfModifiedSince).In(gmt).Format(time.RFC1123)}
	}
	if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfNoneMatch != nil {
		req.Raw().Header["x-ms-source-if-none-match"] = []string{string(*sourceModifiedAccessConditions.SourceIfNoneMatch)}
	}
	if sourceModifiedAccessConditions != nil && sourceModifiedAccessConditions.SourceIfUnmodifiedSince != nil {
		req.Raw().Header["x-ms-source-if-unmodified-since"] = []string{(*sourceModifiedAccessConditions.SourceIfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
	}
	if options != nil && options.SourceRange != nil {
		req.Raw().Header["x-ms-source-range"] = []string{*options.SourceRange}
	}
	req.Raw().Header["x-ms-version"] = []string{client.version}
	return req, nil
}

// stageBlockFromURLHandleResponse handles the StageBlockFromURL response.
func (client *BlockBlobClient) stageBlockFromURLHandleResponse(resp *http.Response) (BlockBlobClientStageBlockFromURLResponse, error) {
	result := BlockBlobClientStageBlockFromURLResponse{}
	if val := resp.Header.Get("x-ms-client-request-id"); val != "" {
		result.ClientRequestID = &val
	}
	if val := resp.Header.Get("x-ms-content-crc64"); val != "" {
		contentCRC64, err := base64.StdEncoding.DecodeString(val)
		if err != nil {
			return BlockBlobClientStageBlockFromURLResponse{}, err
		}
		result.ContentCRC64 = contentCRC64
	}
	if val := resp.Header.Get("Content-MD5"); val != "" {
		contentMD5, err := base64.StdEncoding.DecodeString(val)
		if err != nil {
			return BlockBlobClientStageBlockFromURLResponse{}, err
		}
		result.ContentMD5 = contentMD5
	}
	if val := resp.Header.Get("Date"); val != "" {
		date, err := time.Parse(time.RFC1123, val)
		if err != nil {
			return BlockBlobClientStageBlockFromURLResponse{}, err
		}
		result.Date = &date
	}
	if val := resp.Header.Get("x-ms-encryption-key-sha256"); val != "" {
		result.EncryptionKeySHA256 = &val
	}
	if val := resp.Header.Get("x-ms-encryption-scope"); val != "" {
		result.EncryptionScope = &val
	}
	if val := resp.Header.Get("x-ms-request-server-encrypted"); val != "" {
		isServerEncrypted, err := strconv.ParseBool(val)
		if err != nil {
			return BlockBlobClientStageBlockFromURLResponse{}, err
		}
		result.IsServerEncrypted = &isServerEncrypted
	}
	if val := resp.Header.Get("x-ms-request-id"); val != "" {
		result.RequestID = &val
	}
	if val := resp.Header.Get("x-ms-version"); val != "" {
		result.Version = &val
	}
	return result, nil
}

// Upload - The Upload Block Blob operation updates the content of an existing block blob. Updating an existing block blob
// overwrites any existing metadata on the blob. Partial updates are not supported with Put
// Blob; the content of the existing blob is overwritten with the content of the new blob. To perform a partial update of
// the content of a block blob, use the Put Block List operation.
// If the operation fails it returns an *azcore.ResponseError type.
//   - contentLength - The length of the request.
//   - body - Initial data
//   - options - BlockBlobClientUploadOptions contains the optional parameters for the BlockBlobClient.Upload method.
//   - BlobHTTPHeaders - BlobHTTPHeaders contains a group of parameters for the BlobClient.SetHTTPHeaders method.
//   - LeaseAccessConditions - LeaseAccessConditions contains a group of parameters for the ContainerClient.GetProperties method.
//   - CPKInfo - CPKInfo contains a group of parameters for the BlobClient.Download method.
//   - CPKScopeInfo - CPKScopeInfo contains a group of parameters for the BlobClient.SetMetadata method.
//   - ModifiedAccessConditions - ModifiedAccessConditions contains a group of parameters for the ContainerClient.Delete method.
func (client *BlockBlobClient) Upload(ctx context.Context, contentLength int64, body io.ReadSeekCloser, options *BlockBlobClientUploadOptions, blobHTTPHeaders *BlobHTTPHeaders, leaseAccessConditions *LeaseAccessConditions, cpkInfo *CPKInfo, cpkScopeInfo *CPKScopeInfo, modifiedAccessConditions *ModifiedAccessConditions) (BlockBlobClientUploadResponse, error) {
	var err error
	req, err := client.uploadCreateRequest(ctx, contentLength, body, options, blobHTTPHeaders, leaseAccessConditions, cpkInfo, cpkScopeInfo, modifiedAccessConditions)
	if err != nil {
		return BlockBlobClientUploadResponse{}, err
	}
	httpResp, err := client.internal.Pipeline().Do(req)
	if err != nil {
		return BlockBlobClientUploadResponse{}, err
	}
	if !runtime.HasStatusCode(httpResp, http.StatusCreated) {
		err = runtime.NewResponseError(httpResp)
		return BlockBlobClientUploadResponse{}, err
	}
	resp, err := client.uploadHandleResponse(httpResp)
	return resp, err
}

// uploadCreateRequest creates the Upload request.
func (client *BlockBlobClient) uploadCreateRequest(ctx context.Context, contentLength int64, body io.ReadSeekCloser, options *BlockBlobClientUploadOptions, blobHTTPHeaders *BlobHTTPHeaders, leaseAccessConditions *LeaseAccessConditions, cpkInfo *CPKInfo, cpkScopeInfo *CPKScopeInfo, modifiedAccessConditions *ModifiedAccessConditions) (*policy.Request, error) {
	req, err := runtime.NewRequest(ctx, http.MethodPut, client.endpoint)
	if err != nil {
		return nil, err
	}
	reqQP := req.Raw().URL.Query()
	if options != nil && options.Timeout != nil {
		reqQP.Set("timeout", strconv.FormatInt(int64(*options.Timeout), 10))
	}
	req.Raw().URL.RawQuery = strings.ReplaceAll(reqQP.Encode(), "+", "%20")
	req.Raw().Header["Accept"] = []string{"application/xml"}
	req.Raw().Header["Content-Length"] = []string{strconv.FormatInt(contentLength, 10)}
	if options != nil && options.TransactionalContentMD5 != nil {
		req.Raw().Header["Content-MD5"] = []string{base64.StdEncoding.EncodeToString(options.TransactionalContentMD5)}
	}
	if modifiedAccessConditions != nil && modifiedAccessConditions.IfMatch != nil {
		req.Raw().Header["If-Match"] = []string{string(*modifiedAccessConditions.IfMatch)}
	}
	if modifiedAccessConditions != nil && modifiedAccessConditions.IfModifiedSince != nil {
		req.Raw().Header["If-Modified-Since"] = []string{(*modifiedAccessConditions.IfModifiedSince).In(gmt).Format(time.RFC1123)}
	}
	if modifiedAccessConditions != nil && modifiedAccessConditions.IfNoneMatch != nil {
		req.Raw().Header["If-None-Match"] = []string{string(*modifiedAccessConditions.IfNoneMatch)}
	}
	if modifiedAccessConditions != nil && modifiedAccessConditions.IfUnmodifiedSince != nil {
		req.Raw().Header["If-Unmodified-Since"] = []string{(*modifiedAccessConditions.IfUnmodifiedSince).In(gmt).Format(time.RFC1123)}
	}
	if options != nil && options.Tier != nil {
		req.Raw().Header["x-ms-access-tier"] = []string{string(*options.Tier)}
	}
	if blobHTTPHeaders != nil && blobHTTPHeaders.BlobCacheControl != nil {
		req.Raw().Header["x-ms-blob-cache-control"] = []string{*blobHTTPHeaders.BlobCacheControl}
	}
	if blobHTTPHeaders != nil && blobHTTPHeaders.BlobContentDisposition != nil {
		req.Raw().Header["x-ms-blob-content-disposition"] = []string{*blobHTTPHeaders.BlobContentDisposition}
	}
	if blobHTTPHeaders != nil && blobHTTPHeaders.BlobContentEncoding != nil {
		req.Raw().Header["x-ms-blob-content-encoding"] = []string{*blobHTTPHeaders.BlobContentEncoding}
	}
	if blobHTTPHeaders != nil && blobHTTPHeaders.BlobContentLanguage != nil {
		req.Raw().Header["x-ms-blob-content-language"] = []string{*blobHTTPHeaders.BlobContentLanguage}
	}
	if blobHTTPHeaders != nil && blobHTTPHeaders.BlobContentMD5 != nil {
		req.Raw().Header["x-ms-blob-content-md5"] = []string{base64.StdEncoding.EncodeToString(blobHTTPHeaders.BlobContentMD5)}
	}
	if blobHTTPHeaders != nil && blobHTTPHeaders.BlobContentType != nil {
		req.Raw().Header["x-ms-blob-content-type"] = []string{*blobHTTPHeaders.BlobContentType}
	}
	req.Raw().Header["x-ms-blob-type"] = []string{"BlockBlob"}
	if options != nil && options.RequestID != nil {
		req.Raw().Header["x-ms-client-request-id"] = []string{*options.RequestID}
	}
	if options != nil && options.TransactionalContentCRC64 != nil {
		req.Raw().Header["x-ms-content-crc64"] = []string{base64.StdEncoding.EncodeToString(options.TransactionalContentCRC64)}
	}
	if cpkInfo != nil && cpkInfo.EncryptionAlgorithm != nil {
		req.Raw().Header["x-ms-encryption-algorithm"] = []string{string(*cpkInfo.EncryptionAlgorithm)}
	}
	if cpkInfo != nil && cpkInfo.EncryptionKey != nil {
		req.Raw().Header["x-ms-encryption-key"] = []string{*cpkInfo.EncryptionKey}
	}
	if cpkInfo != nil && cpkInfo.EncryptionKeySHA256 != nil {
		req.Raw().Header["x-ms-encryption-key-sha256"] = []string{*cpkInfo.EncryptionKeySHA256}
	}
	if cpkScopeInfo != nil && cpkScopeInfo.EncryptionScope != nil {
		req.Raw().Header["x-ms-encryption-scope"] = []string{*cpkScopeInfo.EncryptionScope}
	}
	if modifiedAccessConditions != nil && modifiedAccessConditions.IfTags != nil {
		req.Raw().Header["x-ms-if-tags"] = []string{*modifiedAccessConditions.IfTags}
	}
	if options != nil && options.ImmutabilityPolicyMode != nil {
		req.Raw().Header["x-ms-immutability-policy-mode"] = []string{string(*options.ImmutabilityPolicyMode)}
	}
	if options != nil && options.ImmutabilityPolicyExpiry != nil {
		req.Raw().Header["x-ms-immutability-policy-until-date"] = []string{(*options.ImmutabilityPolicyExpiry).In(gmt).Format(time.RFC1123)}
	}
	if leaseAccessConditions != nil && leaseAccessConditions.LeaseID != nil {
		req.Raw().Header["x-ms-lease-id"] = []string{*leaseAccessConditions.LeaseID}
	}
	if options != nil && options.LegalHold != nil {
		req.Raw().Header["x-ms-legal-hold"] = []string{strconv.FormatBool(*options.LegalHold)}
	}
	if options != nil && options.Metadata != nil {
		for k, v := range options.Metadata {
			if v != nil {
				req.Raw().Header["x-ms-meta-"+k] = []string{*v}
			}
		}
	}
	if options != nil && options.StructuredBodyType != nil {
		req.Raw().Header["x-ms-structured-body"] = []string{*options.StructuredBodyType}
	}
	if options != nil && options.StructuredContentLength != nil {
		req.Raw().Header["x-ms-structured-content-length"] = []string{strconv.FormatInt(*options.StructuredContentLength, 10)}
	}
	if options != nil && options.BlobTagsString != nil {
		req.Raw().Header["x-ms-tags"] = []string{*options.BlobTagsString}
	}
	req.Raw().Header["x-ms-version"] = []string{client.version}
	if err := req.SetBody(body, "application/octet-stream"); err != nil {
		return nil, err
	}
	return req, nil
}

// uploadHandleResponse handles the Upload response.
func (client *BlockBlobClient) uploadHandleResponse(resp *http.Response) (BlockBlobClientUploadResponse, error) {
	result := BlockBlobClientUploadResponse{}
	if val := resp.Header.Get("x-ms-client-request-id"); val != "" {
		result.ClientRequestID = &val
	}
	if val := resp.Header.Get("x-ms-content-crc64"); val != "" {
		contentCRC64, err := base64.StdEncoding.DecodeString(val)
		if err != nil {
			return BlockBlobClientUploadResponse{}, err
		}
		result.ContentCRC64 = contentCRC64
	}
	if val := resp.Header.Get("Content-MD5"); val != "" {
		contentMD5, err := base64.StdEncoding.DecodeString(val)
		if err != nil {
			return BlockBlobClientUploadResponse{}, err
		}
		result.ContentMD5 = contentMD5
	}
	if val := resp.Header.Get("Date"); val != "" {
		date, err := time.Parse(time.RFC1123, val)
		if err != nil {
			return BlockBlobClientUploadResponse{}, err
		}
		result.Date = &date
	}
	if val := resp.Header.Get("ETag"); val != "" {
		result.ETag = (*azcore.ETag)(&val)
	}
	if val := resp.Header.Get("x-ms-encryption-key-sha256"); val != "" {
		result.EncryptionKeySHA256 = &val
	}
	if val := resp.Header.Get("x-ms-encryption-scope"); val != "" {
		result.EncryptionScope = &val
	}
	if val := resp.Header.Get("x-ms-request-server-encrypted"); val != "" {
		isServerEncrypted, err := strconv.ParseBool(val)
		if err != nil {
			return BlockBlobClientUploadResponse{}, err
		}
		result.IsServerEncrypted = &isServerEncrypted
	}
	if val := resp.Header.Get("Last-Modified"); val != "" {
		lastModified, err := time.Parse(time.RFC1123, val)
		if err != nil {
			return BlockBlobClientUploadResponse{}, err
		}
		result.LastModified = &lastModified
	}
	if val := resp.Header.Get("x-ms-request-id"); val != "" {
		result.RequestID = &val
	}
	if val := resp.Header.Get("x-ms-structured-body"); val != "" {
		result.StructuredBodyType = &val
	}
	if val := resp.Header.Get("x-ms-version"); val != "" {
		result.Version = &val
	}
	if val := resp.Header.Get("x-ms-version-id"); val != "" {
		result.VersionID = &val
	}
	return result, nil
}
