package azblob

// Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.

import (
	"context"
	"encoding/base64"
	"encoding/xml"
	"github.com/Azure/azure-pipeline-go/pipeline"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"
	"time"
)

// pageBlobClient is the client for the PageBlob methods of the Azblob service.
type pageBlobClient struct {
	managementClient
}

// newPageBlobClient creates an instance of the pageBlobClient client.
func newPageBlobClient(url url.URL, p pipeline.Pipeline) pageBlobClient {
	return pageBlobClient{newManagementClient(url, p)}
}

// ClearPages the Clear Pages operation clears a set of pages from a page blob
//
// contentLength is the length of the request. timeout is the timeout parameter is expressed in seconds. For more
// information, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
// Timeouts for Blob Service Operations.</a> rangeParameter is return only the bytes of the blob in the specified
// range. leaseID is if specified, the operation only succeeds if the resource's lease is active and matches this ID.
// encryptionKey is optional. Specifies the encryption key to use to encrypt the data provided in the request. If not
// specified, encryption is performed with the root account encryption key.  For more information, see Encryption at
// Rest for Azure Storage Services. encryptionKeySha256 is the SHA-256 hash of the provided encryption key. Must be
// provided if the x-ms-encryption-key header is provided. encryptionAlgorithm is the algorithm used to produce the
// encryption key hash. Currently, the only accepted value is "AES256". Must be provided if the x-ms-encryption-key
// header is provided. encryptionScope is optional. Version 2019-07-07 and later.  Specifies the name of the encryption
// scope to use to encrypt the data provided in the request. If not specified, encryption is performed with the default
// account encryption scope.  For more information, see Encryption at Rest for Azure Storage Services.
// ifSequenceNumberLessThanOrEqualTo is specify this header value to operate only on a blob if it has a sequence number
// less than or equal to the specified. ifSequenceNumberLessThan is specify this header value to operate only on a blob
// if it has a sequence number less than the specified. ifSequenceNumberEqualTo is specify this header value to operate
// only on a blob if it has the specified sequence number. ifModifiedSince is specify this header value to operate only
// on a blob if it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to
// operate only on a blob if it has not been modified since the specified date/time. ifMatch is specify an ETag value
// to operate only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs
// without a matching value. ifTags is specify a SQL where clause on blob tags to operate only on blobs with a matching
// value. requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
// analytics logs when storage analytics logging is enabled.
func (client pageBlobClient) ClearPages(ctx context.Context, contentLength int64, timeout *int32, rangeParameter *string, leaseID *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string) (*PageBlobClearPagesResponse, error) {
	if err := validate([]validation{
		{targetValue: timeout,
			constraints: []constraint{{target: "timeout", name: null, rule: false,
				chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
		return nil, err
	}
	req, err := client.clearPagesPreparer(contentLength, timeout, rangeParameter, leaseID, encryptionKey, encryptionKeySha256, encryptionAlgorithm, encryptionScope, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, ifTags, requestID)
	if err != nil {
		return nil, err
	}
	resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.clearPagesResponder}, req)
	if err != nil {
		return nil, err
	}
	return resp.(*PageBlobClearPagesResponse), err
}

// clearPagesPreparer prepares the ClearPages request.
func (client pageBlobClient) clearPagesPreparer(contentLength int64, timeout *int32, rangeParameter *string, leaseID *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string) (pipeline.Request, error) {
	req, err := pipeline.NewRequest("PUT", client.url, nil)
	if err != nil {
		return req, pipeline.NewError(err, "failed to create request")
	}
	params := req.URL.Query()
	if timeout != nil {
		params.Set("timeout", strconv.FormatInt(int64(*timeout), 10))
	}
	params.Set("comp", "page")
	req.URL.RawQuery = params.Encode()
	req.Header.Set("Content-Length", strconv.FormatInt(contentLength, 10))
	if rangeParameter != nil {
		req.Header.Set("x-ms-range", *rangeParameter)
	}
	if leaseID != nil {
		req.Header.Set("x-ms-lease-id", *leaseID)
	}
	if encryptionKey != nil {
		req.Header.Set("x-ms-encryption-key", *encryptionKey)
	}
	if encryptionKeySha256 != nil {
		req.Header.Set("x-ms-encryption-key-sha256", *encryptionKeySha256)
	}
	if encryptionAlgorithm != EncryptionAlgorithmNone {
		req.Header.Set("x-ms-encryption-algorithm", string(encryptionAlgorithm))
	}
	if encryptionScope != nil {
		req.Header.Set("x-ms-encryption-scope", *encryptionScope)
	}
	if ifSequenceNumberLessThanOrEqualTo != nil {
		req.Header.Set("x-ms-if-sequence-number-le", strconv.FormatInt(*ifSequenceNumberLessThanOrEqualTo, 10))
	}
	if ifSequenceNumberLessThan != nil {
		req.Header.Set("x-ms-if-sequence-number-lt", strconv.FormatInt(*ifSequenceNumberLessThan, 10))
	}
	if ifSequenceNumberEqualTo != nil {
		req.Header.Set("x-ms-if-sequence-number-eq", strconv.FormatInt(*ifSequenceNumberEqualTo, 10))
	}
	if ifModifiedSince != nil {
		req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123))
	}
	if ifUnmodifiedSince != nil {
		req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
	}
	if ifMatch != nil {
		req.Header.Set("If-Match", string(*ifMatch))
	}
	if ifNoneMatch != nil {
		req.Header.Set("If-None-Match", string(*ifNoneMatch))
	}
	if ifTags != nil {
		req.Header.Set("x-ms-if-tags", *ifTags)
	}
	req.Header.Set("x-ms-version", ServiceVersion)
	if requestID != nil {
		req.Header.Set("x-ms-client-request-id", *requestID)
	}
	req.Header.Set("x-ms-page-write", "clear")
	return req, nil
}

// clearPagesResponder handles the response to the ClearPages request.
func (client pageBlobClient) clearPagesResponder(resp pipeline.Response) (pipeline.Response, error) {
	err := validateResponse(resp, http.StatusOK, http.StatusCreated)
	if resp == nil {
		return nil, err
	}
	io.Copy(ioutil.Discard, resp.Response().Body)
	resp.Response().Body.Close()
	return &PageBlobClearPagesResponse{rawResponse: resp.Response()}, err
}

// CopyIncremental the Copy Incremental operation copies a snapshot of the source page blob to a destination page blob.
// The snapshot is copied such that only the differential changes between the previously copied snapshot are
// transferred to the destination. The copied snapshots are complete copies of the original snapshot and can be read or
// copied from as usual. This API is supported since REST version 2016-05-31.
//
// copySource is 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. timeout is the timeout parameter is
// expressed in seconds. For more information, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
// Timeouts for Blob Service Operations.</a> ifModifiedSince is specify this header value to operate only on a blob if
// it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only
// on a blob if it has not been modified since the specified date/time. ifMatch is specify an ETag value to operate
// only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a
// matching value. ifTags is specify a SQL where clause on blob tags to operate only on blobs with a matching value.
// requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics
// logs when storage analytics logging is enabled.
func (client pageBlobClient) CopyIncremental(ctx context.Context, copySource string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string) (*PageBlobCopyIncrementalResponse, error) {
	if err := validate([]validation{
		{targetValue: timeout,
			constraints: []constraint{{target: "timeout", name: null, rule: false,
				chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
		return nil, err
	}
	req, err := client.copyIncrementalPreparer(copySource, timeout, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, ifTags, requestID)
	if err != nil {
		return nil, err
	}
	resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.copyIncrementalResponder}, req)
	if err != nil {
		return nil, err
	}
	return resp.(*PageBlobCopyIncrementalResponse), err
}

// copyIncrementalPreparer prepares the CopyIncremental request.
func (client pageBlobClient) copyIncrementalPreparer(copySource string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string) (pipeline.Request, error) {
	req, err := pipeline.NewRequest("PUT", client.url, nil)
	if err != nil {
		return req, pipeline.NewError(err, "failed to create request")
	}
	params := req.URL.Query()
	if timeout != nil {
		params.Set("timeout", strconv.FormatInt(int64(*timeout), 10))
	}
	params.Set("comp", "incrementalcopy")
	req.URL.RawQuery = params.Encode()
	if ifModifiedSince != nil {
		req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123))
	}
	if ifUnmodifiedSince != nil {
		req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
	}
	if ifMatch != nil {
		req.Header.Set("If-Match", string(*ifMatch))
	}
	if ifNoneMatch != nil {
		req.Header.Set("If-None-Match", string(*ifNoneMatch))
	}
	if ifTags != nil {
		req.Header.Set("x-ms-if-tags", *ifTags)
	}
	req.Header.Set("x-ms-copy-source", copySource)
	req.Header.Set("x-ms-version", ServiceVersion)
	if requestID != nil {
		req.Header.Set("x-ms-client-request-id", *requestID)
	}
	return req, nil
}

// copyIncrementalResponder handles the response to the CopyIncremental request.
func (client pageBlobClient) copyIncrementalResponder(resp pipeline.Response) (pipeline.Response, error) {
	err := validateResponse(resp, http.StatusOK, http.StatusAccepted)
	if resp == nil {
		return nil, err
	}
	io.Copy(ioutil.Discard, resp.Response().Body)
	resp.Response().Body.Close()
	return &PageBlobCopyIncrementalResponse{rawResponse: resp.Response()}, err
}

// Create the Create operation creates a new page blob.
//
// contentLength is the length of the request. blobContentLength is this header specifies the maximum size for the page
// blob, up to 1 TB. The page blob size must be aligned to a 512-byte boundary. timeout is the timeout parameter is
// expressed in seconds. For more information, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
// Timeouts for Blob Service Operations.</a> tier is optional. Indicates the tier to be set on the page blob.
// blobContentType is optional. Sets the blob's content type. If specified, this property is stored with the blob and
// returned with a read request. blobContentEncoding is optional. Sets the blob's content encoding. If specified, this
// property is stored with the blob and returned with a read request. blobContentLanguage is optional. Set the blob's
// content language. If specified, this property is stored with the blob and returned with a read request.
// blobContentMD5 is optional. An MD5 hash of the blob content. Note that this hash is not validated, as the hashes for
// the individual blocks were validated when each was uploaded. blobCacheControl is optional. Sets the blob's cache
// control. If specified, this property is stored with the blob and returned with a read request. metadata is optional.
// Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the
// operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value
// pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from
// the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules
// for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. leaseID is if
// specified, the operation only succeeds if the resource's lease is active and matches this ID. blobContentDisposition
// is optional. Sets the blob's Content-Disposition header. encryptionKey is optional. Specifies the encryption key to
// use to encrypt the data provided in the request. If not specified, encryption is performed with the root account
// encryption key.  For more information, see Encryption at Rest for Azure Storage Services. encryptionKeySha256 is the
// SHA-256 hash of the provided encryption key. Must be provided if the x-ms-encryption-key header is provided.
// encryptionAlgorithm is the algorithm used to produce the encryption key hash. Currently, the only accepted value is
// "AES256". Must be provided if the x-ms-encryption-key header is provided. encryptionScope is optional. Version
// 2019-07-07 and later.  Specifies the name of the encryption scope to use to encrypt the data provided in the
// request. If not specified, encryption is performed with the default account encryption scope.  For more information,
// see Encryption at Rest for Azure Storage Services. ifModifiedSince is specify this header value to operate only on a
// blob if it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to
// operate only on a blob if it has not been modified since the specified date/time. ifMatch is specify an ETag value
// to operate only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs
// without a matching value. ifTags is specify a SQL where clause on blob tags to operate only on blobs with a matching
// value. blobSequenceNumber is set for page blobs only. The sequence number is a user-controlled value that you can
// use to track requests. The value of the sequence number must be between 0 and 2^63 - 1. requestID is provides a
// client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage
// analytics logging is enabled. blobTagsString is optional.  Used to set blob tags in various blob operations.
// immutabilityPolicyExpiry is specifies the date time when the blobs immutability policy is set to expire.
// immutabilityPolicyMode is specifies the immutability policy mode to set on the blob. legalHold is specified if a
// legal hold should be set on the blob.
func (client pageBlobClient) Create(ctx context.Context, contentLength int64, blobContentLength int64, timeout *int32, tier PremiumPageBlobAccessTierType, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, blobSequenceNumber *int64, requestID *string, blobTagsString *string, immutabilityPolicyExpiry *time.Time, immutabilityPolicyMode BlobImmutabilityPolicyModeType, legalHold *bool) (*PageBlobCreateResponse, error) {
	if err := validate([]validation{
		{targetValue: timeout,
			constraints: []constraint{{target: "timeout", name: null, rule: false,
				chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
		return nil, err
	}
	req, err := client.createPreparer(contentLength, blobContentLength, timeout, tier, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, blobCacheControl, metadata, leaseID, blobContentDisposition, encryptionKey, encryptionKeySha256, encryptionAlgorithm, encryptionScope, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, ifTags, blobSequenceNumber, requestID, blobTagsString, immutabilityPolicyExpiry, immutabilityPolicyMode, legalHold)
	if err != nil {
		return nil, err
	}
	resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.createResponder}, req)
	if err != nil {
		return nil, err
	}
	return resp.(*PageBlobCreateResponse), err
}

// createPreparer prepares the Create request.
func (client pageBlobClient) createPreparer(contentLength int64, blobContentLength int64, timeout *int32, tier PremiumPageBlobAccessTierType, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, blobSequenceNumber *int64, requestID *string, blobTagsString *string, immutabilityPolicyExpiry *time.Time, immutabilityPolicyMode BlobImmutabilityPolicyModeType, legalHold *bool) (pipeline.Request, error) {
	req, err := pipeline.NewRequest("PUT", client.url, nil)
	if err != nil {
		return req, pipeline.NewError(err, "failed to create request")
	}
	params := req.URL.Query()
	if timeout != nil {
		params.Set("timeout", strconv.FormatInt(int64(*timeout), 10))
	}
	req.URL.RawQuery = params.Encode()
	req.Header.Set("Content-Length", strconv.FormatInt(contentLength, 10))
	if tier != PremiumPageBlobAccessTierNone {
		req.Header.Set("x-ms-access-tier", string(tier))
	}
	if blobContentType != nil {
		req.Header.Set("x-ms-blob-content-type", *blobContentType)
	}
	if blobContentEncoding != nil {
		req.Header.Set("x-ms-blob-content-encoding", *blobContentEncoding)
	}
	if blobContentLanguage != nil {
		req.Header.Set("x-ms-blob-content-language", *blobContentLanguage)
	}
	if blobContentMD5 != nil {
		req.Header.Set("x-ms-blob-content-md5", base64.StdEncoding.EncodeToString(blobContentMD5))
	}
	if blobCacheControl != nil {
		req.Header.Set("x-ms-blob-cache-control", *blobCacheControl)
	}
	if metadata != nil {
		for k, v := range metadata {
			req.Header.Set("x-ms-meta-"+k, v)
		}
	}
	if leaseID != nil {
		req.Header.Set("x-ms-lease-id", *leaseID)
	}
	if blobContentDisposition != nil {
		req.Header.Set("x-ms-blob-content-disposition", *blobContentDisposition)
	}
	if encryptionKey != nil {
		req.Header.Set("x-ms-encryption-key", *encryptionKey)
	}
	if encryptionKeySha256 != nil {
		req.Header.Set("x-ms-encryption-key-sha256", *encryptionKeySha256)
	}
	if encryptionAlgorithm != EncryptionAlgorithmNone {
		req.Header.Set("x-ms-encryption-algorithm", string(encryptionAlgorithm))
	}
	if encryptionScope != nil {
		req.Header.Set("x-ms-encryption-scope", *encryptionScope)
	}
	if ifModifiedSince != nil {
		req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123))
	}
	if ifUnmodifiedSince != nil {
		req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
	}
	if ifMatch != nil {
		req.Header.Set("If-Match", string(*ifMatch))
	}
	if ifNoneMatch != nil {
		req.Header.Set("If-None-Match", string(*ifNoneMatch))
	}
	if ifTags != nil {
		req.Header.Set("x-ms-if-tags", *ifTags)
	}
	req.Header.Set("x-ms-blob-content-length", strconv.FormatInt(blobContentLength, 10))
	if blobSequenceNumber != nil {
		req.Header.Set("x-ms-blob-sequence-number", strconv.FormatInt(*blobSequenceNumber, 10))
	}
	req.Header.Set("x-ms-version", ServiceVersion)
	if requestID != nil {
		req.Header.Set("x-ms-client-request-id", *requestID)
	}
	if blobTagsString != nil {
		req.Header.Set("x-ms-tags", *blobTagsString)
	}
	if immutabilityPolicyExpiry != nil {
		req.Header.Set("x-ms-immutability-policy-until-date", (*immutabilityPolicyExpiry).In(gmt).Format(time.RFC1123))
	}
	if immutabilityPolicyMode != BlobImmutabilityPolicyModeNone {
		req.Header.Set("x-ms-immutability-policy-mode", string(immutabilityPolicyMode))
	}
	if legalHold != nil {
		req.Header.Set("x-ms-legal-hold", strconv.FormatBool(*legalHold))
	}
	req.Header.Set("x-ms-blob-type", "PageBlob")
	return req, nil
}

// createResponder handles the response to the Create request.
func (client pageBlobClient) createResponder(resp pipeline.Response) (pipeline.Response, error) {
	err := validateResponse(resp, http.StatusOK, http.StatusCreated)
	if resp == nil {
		return nil, err
	}
	io.Copy(ioutil.Discard, resp.Response().Body)
	resp.Response().Body.Close()
	return &PageBlobCreateResponse{rawResponse: resp.Response()}, err
}

// GetPageRanges the Get Page Ranges operation returns the list of valid page ranges for a page blob or snapshot of a
// page blob
//
// snapshot is the snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to
// retrieve. For more information on working with blob snapshots, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating
// a Snapshot of a Blob.</a> timeout is the timeout parameter is expressed in seconds. For more information, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
// Timeouts for Blob Service Operations.</a> rangeParameter is return only the bytes of the blob in the specified
// range. leaseID is if specified, the operation only succeeds if the resource's lease is active and matches this ID.
// ifModifiedSince is specify this header value to operate only on a blob if it has been modified since the specified
// date/time. ifUnmodifiedSince is specify this header value to operate only on a blob if it has not been modified
// since the specified date/time. ifMatch is specify an ETag value to operate only on blobs with a matching value.
// ifNoneMatch is specify an ETag value to operate only on blobs without a matching value. ifTags is specify a SQL
// where clause on blob tags to operate only on blobs with a matching value. requestID is provides a client-generated,
// opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is
// enabled.
func (client pageBlobClient) GetPageRanges(ctx context.Context, snapshot *string, timeout *int32, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string) (*PageList, error) {
	if err := validate([]validation{
		{targetValue: timeout,
			constraints: []constraint{{target: "timeout", name: null, rule: false,
				chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
		return nil, err
	}
	req, err := client.getPageRangesPreparer(snapshot, timeout, rangeParameter, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, ifTags, requestID)
	if err != nil {
		return nil, err
	}
	resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.getPageRangesResponder}, req)
	if err != nil {
		return nil, err
	}
	return resp.(*PageList), err
}

// getPageRangesPreparer prepares the GetPageRanges request.
func (client pageBlobClient) getPageRangesPreparer(snapshot *string, timeout *int32, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string) (pipeline.Request, error) {
	req, err := pipeline.NewRequest("GET", client.url, nil)
	if err != nil {
		return req, pipeline.NewError(err, "failed to create request")
	}
	params := req.URL.Query()
	if snapshot != nil && len(*snapshot) > 0 {
		params.Set("snapshot", *snapshot)
	}
	if timeout != nil {
		params.Set("timeout", strconv.FormatInt(int64(*timeout), 10))
	}
	params.Set("comp", "pagelist")
	req.URL.RawQuery = params.Encode()
	if rangeParameter != nil {
		req.Header.Set("x-ms-range", *rangeParameter)
	}
	if leaseID != nil {
		req.Header.Set("x-ms-lease-id", *leaseID)
	}
	if ifModifiedSince != nil {
		req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123))
	}
	if ifUnmodifiedSince != nil {
		req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
	}
	if ifMatch != nil {
		req.Header.Set("If-Match", string(*ifMatch))
	}
	if ifNoneMatch != nil {
		req.Header.Set("If-None-Match", string(*ifNoneMatch))
	}
	if ifTags != nil {
		req.Header.Set("x-ms-if-tags", *ifTags)
	}
	req.Header.Set("x-ms-version", ServiceVersion)
	if requestID != nil {
		req.Header.Set("x-ms-client-request-id", *requestID)
	}
	return req, nil
}

// getPageRangesResponder handles the response to the GetPageRanges request.
func (client pageBlobClient) getPageRangesResponder(resp pipeline.Response) (pipeline.Response, error) {
	err := validateResponse(resp, http.StatusOK)
	if resp == nil {
		return nil, err
	}
	result := &PageList{rawResponse: resp.Response()}
	if err != nil {
		return result, err
	}
	defer resp.Response().Body.Close()
	b, err := ioutil.ReadAll(resp.Response().Body)
	if err != nil {
		return result, err
	}
	if len(b) > 0 {
		b = removeBOM(b)
		err = xml.Unmarshal(b, result)
		if err != nil {
			return result, NewResponseError(err, resp.Response(), "failed to unmarshal response body")
		}
	}
	return result, nil
}

// GetPageRangesDiff the Get Page Ranges Diff operation returns the list of valid page ranges for a page blob that were
// changed between target blob and previous snapshot.
//
// snapshot is the snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to
// retrieve. For more information on working with blob snapshots, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating
// a Snapshot of a Blob.</a> timeout is the timeout parameter is expressed in seconds. For more information, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
// Timeouts for Blob Service Operations.</a> prevsnapshot is optional in version 2015-07-08 and newer. The prevsnapshot
// parameter is a DateTime value that specifies that the response will contain only pages that were changed between
// target blob and previous snapshot. Changed pages include both updated and cleared pages. The target blob may be a
// snapshot, as long as the snapshot specified by prevsnapshot is the older of the two. Note that incremental snapshots
// are currently supported only for blobs created on or after January 1, 2016. prevSnapshotURL is optional. This header
// is only supported in service versions 2019-04-19 and after and specifies the URL of a previous snapshot of the
// target blob. The response will only contain pages that were changed between the target blob and its previous
// snapshot. rangeParameter is return only the bytes of the blob in the specified range. leaseID is if specified, the
// operation only succeeds if the resource's lease is active and matches this ID. ifModifiedSince is specify this
// header value to operate only on a blob if it has been modified since the specified date/time. ifUnmodifiedSince is
// specify this header value to operate only on a blob if it has not been modified since the specified date/time.
// ifMatch is specify an ETag value to operate only on blobs with a matching value. ifNoneMatch is specify an ETag
// value to operate only on blobs without a matching value. ifTags is specify a SQL where clause on blob tags to
// operate only on blobs with a matching value. requestID is provides a client-generated, opaque value with a 1 KB
// character limit that is recorded in the analytics logs when storage analytics logging is enabled.
func (client pageBlobClient) GetPageRangesDiff(ctx context.Context, snapshot *string, timeout *int32, prevsnapshot *string, prevSnapshotURL *string, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string) (*PageList, error) {
	if err := validate([]validation{
		{targetValue: timeout,
			constraints: []constraint{{target: "timeout", name: null, rule: false,
				chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
		return nil, err
	}
	req, err := client.getPageRangesDiffPreparer(snapshot, timeout, prevsnapshot, prevSnapshotURL, rangeParameter, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, ifTags, requestID)
	if err != nil {
		return nil, err
	}
	resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.getPageRangesDiffResponder}, req)
	if err != nil {
		return nil, err
	}
	return resp.(*PageList), err
}

// getPageRangesDiffPreparer prepares the GetPageRangesDiff request.
func (client pageBlobClient) getPageRangesDiffPreparer(snapshot *string, timeout *int32, prevsnapshot *string, prevSnapshotURL *string, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string) (pipeline.Request, error) {
	req, err := pipeline.NewRequest("GET", client.url, nil)
	if err != nil {
		return req, pipeline.NewError(err, "failed to create request")
	}
	params := req.URL.Query()
	if snapshot != nil && len(*snapshot) > 0 {
		params.Set("snapshot", *snapshot)
	}
	if timeout != nil {
		params.Set("timeout", strconv.FormatInt(int64(*timeout), 10))
	}
	if prevsnapshot != nil && len(*prevsnapshot) > 0 {
		params.Set("prevsnapshot", *prevsnapshot)
	}
	params.Set("comp", "pagelist")
	req.URL.RawQuery = params.Encode()
	if prevSnapshotURL != nil {
		req.Header.Set("x-ms-previous-snapshot-url", *prevSnapshotURL)
	}
	if rangeParameter != nil {
		req.Header.Set("x-ms-range", *rangeParameter)
	}
	if leaseID != nil {
		req.Header.Set("x-ms-lease-id", *leaseID)
	}
	if ifModifiedSince != nil {
		req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123))
	}
	if ifUnmodifiedSince != nil {
		req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
	}
	if ifMatch != nil {
		req.Header.Set("If-Match", string(*ifMatch))
	}
	if ifNoneMatch != nil {
		req.Header.Set("If-None-Match", string(*ifNoneMatch))
	}
	if ifTags != nil {
		req.Header.Set("x-ms-if-tags", *ifTags)
	}
	req.Header.Set("x-ms-version", ServiceVersion)
	if requestID != nil {
		req.Header.Set("x-ms-client-request-id", *requestID)
	}
	return req, nil
}

// getPageRangesDiffResponder handles the response to the GetPageRangesDiff request.
func (client pageBlobClient) getPageRangesDiffResponder(resp pipeline.Response) (pipeline.Response, error) {
	err := validateResponse(resp, http.StatusOK)
	if resp == nil {
		return nil, err
	}
	result := &PageList{rawResponse: resp.Response()}
	if err != nil {
		return result, err
	}
	defer resp.Response().Body.Close()
	b, err := ioutil.ReadAll(resp.Response().Body)
	if err != nil {
		return result, err
	}
	if len(b) > 0 {
		b = removeBOM(b)
		err = xml.Unmarshal(b, result)
		if err != nil {
			return result, NewResponseError(err, resp.Response(), "failed to unmarshal response body")
		}
	}
	return result, nil
}

// Resize resize the Blob
//
// blobContentLength is this header specifies the maximum size for the page blob, up to 1 TB. The page blob size must
// be aligned to a 512-byte boundary. timeout is the timeout parameter is expressed in seconds. For more information,
// see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
// Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the resource's
// lease is active and matches this ID. encryptionKey is optional. Specifies the encryption key to use to encrypt the
// data provided in the request. If not specified, encryption is performed with the root account encryption key.  For
// more information, see Encryption at Rest for Azure Storage Services. encryptionKeySha256 is the SHA-256 hash of the
// provided encryption key. Must be provided if the x-ms-encryption-key header is provided. encryptionAlgorithm is the
// algorithm used to produce the encryption key hash. Currently, the only accepted value is "AES256". Must be provided
// if the x-ms-encryption-key header is provided. encryptionScope is optional. Version 2019-07-07 and later.  Specifies
// the name of the encryption scope to use to encrypt the data provided in the request. If not specified, encryption is
// performed with the default account encryption scope.  For more information, see Encryption at Rest for Azure Storage
// Services. ifModifiedSince is specify this header value to operate only on a blob if it has been modified since the
// specified date/time. ifUnmodifiedSince is specify this header value to operate only on a blob if it has not been
// modified since the specified date/time. ifMatch is specify an ETag value to operate only on blobs with a matching
// value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching value. ifTags is specify a
// SQL where clause on blob tags to operate only on blobs with a matching value. requestID is provides a
// client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage
// analytics logging is enabled.
func (client pageBlobClient) Resize(ctx context.Context, blobContentLength int64, timeout *int32, leaseID *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string) (*PageBlobResizeResponse, error) {
	if err := validate([]validation{
		{targetValue: timeout,
			constraints: []constraint{{target: "timeout", name: null, rule: false,
				chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
		return nil, err
	}
	req, err := client.resizePreparer(blobContentLength, timeout, leaseID, encryptionKey, encryptionKeySha256, encryptionAlgorithm, encryptionScope, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, ifTags, requestID)
	if err != nil {
		return nil, err
	}
	resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.resizeResponder}, req)
	if err != nil {
		return nil, err
	}
	return resp.(*PageBlobResizeResponse), err
}

// resizePreparer prepares the Resize request.
func (client pageBlobClient) resizePreparer(blobContentLength int64, timeout *int32, leaseID *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string) (pipeline.Request, error) {
	req, err := pipeline.NewRequest("PUT", client.url, nil)
	if err != nil {
		return req, pipeline.NewError(err, "failed to create request")
	}
	params := req.URL.Query()
	if timeout != nil {
		params.Set("timeout", strconv.FormatInt(int64(*timeout), 10))
	}
	params.Set("comp", "properties")
	req.URL.RawQuery = params.Encode()
	if leaseID != nil {
		req.Header.Set("x-ms-lease-id", *leaseID)
	}
	if encryptionKey != nil {
		req.Header.Set("x-ms-encryption-key", *encryptionKey)
	}
	if encryptionKeySha256 != nil {
		req.Header.Set("x-ms-encryption-key-sha256", *encryptionKeySha256)
	}
	if encryptionAlgorithm != EncryptionAlgorithmNone {
		req.Header.Set("x-ms-encryption-algorithm", string(encryptionAlgorithm))
	}
	if encryptionScope != nil {
		req.Header.Set("x-ms-encryption-scope", *encryptionScope)
	}
	if ifModifiedSince != nil {
		req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123))
	}
	if ifUnmodifiedSince != nil {
		req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
	}
	if ifMatch != nil {
		req.Header.Set("If-Match", string(*ifMatch))
	}
	if ifNoneMatch != nil {
		req.Header.Set("If-None-Match", string(*ifNoneMatch))
	}
	if ifTags != nil {
		req.Header.Set("x-ms-if-tags", *ifTags)
	}
	req.Header.Set("x-ms-blob-content-length", strconv.FormatInt(blobContentLength, 10))
	req.Header.Set("x-ms-version", ServiceVersion)
	if requestID != nil {
		req.Header.Set("x-ms-client-request-id", *requestID)
	}
	return req, nil
}

// resizeResponder handles the response to the Resize request.
func (client pageBlobClient) resizeResponder(resp pipeline.Response) (pipeline.Response, error) {
	err := validateResponse(resp, http.StatusOK)
	if resp == nil {
		return nil, err
	}
	io.Copy(ioutil.Discard, resp.Response().Body)
	resp.Response().Body.Close()
	return &PageBlobResizeResponse{rawResponse: resp.Response()}, err
}

// UpdateSequenceNumber update the sequence number of the blob
//
// sequenceNumberAction is required if the x-ms-blob-sequence-number header is set for the request. This property
// applies to page blobs only. This property indicates how the service should modify the blob's sequence number timeout
// is the timeout parameter is expressed in seconds. For more information, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
// Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the resource's
// lease is active and matches this ID. ifModifiedSince is specify this header value to operate only on a blob if it
// has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only on a
// blob if it has not been modified since the specified date/time. ifMatch is specify an ETag value to operate only on
// blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching value.
// ifTags is specify a SQL where clause on blob tags to operate only on blobs with a matching value. blobSequenceNumber
// is set for page blobs only. The sequence number is a user-controlled value that you can use to track requests. The
// value of the sequence number must be between 0 and 2^63 - 1. requestID is provides a client-generated, opaque value
// with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled.
func (client pageBlobClient) UpdateSequenceNumber(ctx context.Context, sequenceNumberAction SequenceNumberActionType, timeout *int32, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, blobSequenceNumber *int64, requestID *string) (*PageBlobUpdateSequenceNumberResponse, error) {
	if err := validate([]validation{
		{targetValue: timeout,
			constraints: []constraint{{target: "timeout", name: null, rule: false,
				chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
		return nil, err
	}
	req, err := client.updateSequenceNumberPreparer(sequenceNumberAction, timeout, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, ifTags, blobSequenceNumber, requestID)
	if err != nil {
		return nil, err
	}
	resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.updateSequenceNumberResponder}, req)
	if err != nil {
		return nil, err
	}
	return resp.(*PageBlobUpdateSequenceNumberResponse), err
}

// updateSequenceNumberPreparer prepares the UpdateSequenceNumber request.
func (client pageBlobClient) updateSequenceNumberPreparer(sequenceNumberAction SequenceNumberActionType, timeout *int32, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, blobSequenceNumber *int64, requestID *string) (pipeline.Request, error) {
	req, err := pipeline.NewRequest("PUT", client.url, nil)
	if err != nil {
		return req, pipeline.NewError(err, "failed to create request")
	}
	params := req.URL.Query()
	if timeout != nil {
		params.Set("timeout", strconv.FormatInt(int64(*timeout), 10))
	}
	params.Set("comp", "properties")
	req.URL.RawQuery = params.Encode()
	if leaseID != nil {
		req.Header.Set("x-ms-lease-id", *leaseID)
	}
	if ifModifiedSince != nil {
		req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123))
	}
	if ifUnmodifiedSince != nil {
		req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
	}
	if ifMatch != nil {
		req.Header.Set("If-Match", string(*ifMatch))
	}
	if ifNoneMatch != nil {
		req.Header.Set("If-None-Match", string(*ifNoneMatch))
	}
	if ifTags != nil {
		req.Header.Set("x-ms-if-tags", *ifTags)
	}
	req.Header.Set("x-ms-sequence-number-action", string(sequenceNumberAction))
	if blobSequenceNumber != nil {
		req.Header.Set("x-ms-blob-sequence-number", strconv.FormatInt(*blobSequenceNumber, 10))
	}
	req.Header.Set("x-ms-version", ServiceVersion)
	if requestID != nil {
		req.Header.Set("x-ms-client-request-id", *requestID)
	}
	return req, nil
}

// updateSequenceNumberResponder handles the response to the UpdateSequenceNumber request.
func (client pageBlobClient) updateSequenceNumberResponder(resp pipeline.Response) (pipeline.Response, error) {
	err := validateResponse(resp, http.StatusOK)
	if resp == nil {
		return nil, err
	}
	io.Copy(ioutil.Discard, resp.Response().Body)
	resp.Response().Body.Close()
	return &PageBlobUpdateSequenceNumberResponse{rawResponse: resp.Response()}, err
}

// UploadPages the Upload Pages operation writes a range of pages to a page blob
//
// body is initial data body will be closed upon successful return. Callers should ensure closure when receiving an
// error.contentLength is the length of the request. transactionalContentMD5 is specify the transactional md5 for the
// body, to be validated by the service. transactionalContentCrc64 is specify the transactional crc64 for the body, to
// be validated by the service. timeout is the timeout parameter is expressed in seconds. For more information, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
// Timeouts for Blob Service Operations.</a> rangeParameter is return only the bytes of the blob in the specified
// range. leaseID is if specified, the operation only succeeds if the resource's lease is active and matches this ID.
// encryptionKey is optional. Specifies the encryption key to use to encrypt the data provided in the request. If not
// specified, encryption is performed with the root account encryption key.  For more information, see Encryption at
// Rest for Azure Storage Services. encryptionKeySha256 is the SHA-256 hash of the provided encryption key. Must be
// provided if the x-ms-encryption-key header is provided. encryptionAlgorithm is the algorithm used to produce the
// encryption key hash. Currently, the only accepted value is "AES256". Must be provided if the x-ms-encryption-key
// header is provided. encryptionScope is optional. Version 2019-07-07 and later.  Specifies the name of the encryption
// scope to use to encrypt the data provided in the request. If not specified, encryption is performed with the default
// account encryption scope.  For more information, see Encryption at Rest for Azure Storage Services.
// ifSequenceNumberLessThanOrEqualTo is specify this header value to operate only on a blob if it has a sequence number
// less than or equal to the specified. ifSequenceNumberLessThan is specify this header value to operate only on a blob
// if it has a sequence number less than the specified. ifSequenceNumberEqualTo is specify this header value to operate
// only on a blob if it has the specified sequence number. ifModifiedSince is specify this header value to operate only
// on a blob if it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to
// operate only on a blob if it has not been modified since the specified date/time. ifMatch is specify an ETag value
// to operate only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs
// without a matching value. ifTags is specify a SQL where clause on blob tags to operate only on blobs with a matching
// value. requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
// analytics logs when storage analytics logging is enabled.
func (client pageBlobClient) UploadPages(ctx context.Context, body io.ReadSeeker, contentLength int64, transactionalContentMD5 []byte, transactionalContentCrc64 []byte, timeout *int32, rangeParameter *string, leaseID *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string) (*PageBlobUploadPagesResponse, error) {
	if err := validate([]validation{
		{targetValue: body,
			constraints: []constraint{{target: "body", name: null, rule: true, chain: nil}}},
		{targetValue: timeout,
			constraints: []constraint{{target: "timeout", name: null, rule: false,
				chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
		return nil, err
	}
	req, err := client.uploadPagesPreparer(body, contentLength, transactionalContentMD5, transactionalContentCrc64, timeout, rangeParameter, leaseID, encryptionKey, encryptionKeySha256, encryptionAlgorithm, encryptionScope, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, ifTags, requestID)
	if err != nil {
		return nil, err
	}
	resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.uploadPagesResponder}, req)
	if err != nil {
		return nil, err
	}
	return resp.(*PageBlobUploadPagesResponse), err
}

// uploadPagesPreparer prepares the UploadPages request.
func (client pageBlobClient) uploadPagesPreparer(body io.ReadSeeker, contentLength int64, transactionalContentMD5 []byte, transactionalContentCrc64 []byte, timeout *int32, rangeParameter *string, leaseID *string, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, requestID *string) (pipeline.Request, error) {
	req, err := pipeline.NewRequest("PUT", client.url, body)
	if err != nil {
		return req, pipeline.NewError(err, "failed to create request")
	}
	params := req.URL.Query()
	if timeout != nil {
		params.Set("timeout", strconv.FormatInt(int64(*timeout), 10))
	}
	params.Set("comp", "page")
	req.URL.RawQuery = params.Encode()
	req.Header.Set("Content-Length", strconv.FormatInt(contentLength, 10))
	if transactionalContentMD5 != nil {
		req.Header.Set("Content-MD5", base64.StdEncoding.EncodeToString(transactionalContentMD5))
	}
	if transactionalContentCrc64 != nil {
		req.Header.Set("x-ms-content-crc64", base64.StdEncoding.EncodeToString(transactionalContentCrc64))
	}
	if rangeParameter != nil {
		req.Header.Set("x-ms-range", *rangeParameter)
	}
	if leaseID != nil {
		req.Header.Set("x-ms-lease-id", *leaseID)
	}
	if encryptionKey != nil {
		req.Header.Set("x-ms-encryption-key", *encryptionKey)
	}
	if encryptionKeySha256 != nil {
		req.Header.Set("x-ms-encryption-key-sha256", *encryptionKeySha256)
	}
	if encryptionAlgorithm != EncryptionAlgorithmNone {
		req.Header.Set("x-ms-encryption-algorithm", string(encryptionAlgorithm))
	}
	if encryptionScope != nil {
		req.Header.Set("x-ms-encryption-scope", *encryptionScope)
	}
	if ifSequenceNumberLessThanOrEqualTo != nil {
		req.Header.Set("x-ms-if-sequence-number-le", strconv.FormatInt(*ifSequenceNumberLessThanOrEqualTo, 10))
	}
	if ifSequenceNumberLessThan != nil {
		req.Header.Set("x-ms-if-sequence-number-lt", strconv.FormatInt(*ifSequenceNumberLessThan, 10))
	}
	if ifSequenceNumberEqualTo != nil {
		req.Header.Set("x-ms-if-sequence-number-eq", strconv.FormatInt(*ifSequenceNumberEqualTo, 10))
	}
	if ifModifiedSince != nil {
		req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123))
	}
	if ifUnmodifiedSince != nil {
		req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
	}
	if ifMatch != nil {
		req.Header.Set("If-Match", string(*ifMatch))
	}
	if ifNoneMatch != nil {
		req.Header.Set("If-None-Match", string(*ifNoneMatch))
	}
	if ifTags != nil {
		req.Header.Set("x-ms-if-tags", *ifTags)
	}
	req.Header.Set("x-ms-version", ServiceVersion)
	if requestID != nil {
		req.Header.Set("x-ms-client-request-id", *requestID)
	}
	req.Header.Set("x-ms-page-write", "update")
	return req, nil
}

// uploadPagesResponder handles the response to the UploadPages request.
func (client pageBlobClient) uploadPagesResponder(resp pipeline.Response) (pipeline.Response, error) {
	err := validateResponse(resp, http.StatusOK, http.StatusCreated)
	if resp == nil {
		return nil, err
	}
	io.Copy(ioutil.Discard, resp.Response().Body)
	resp.Response().Body.Close()
	return &PageBlobUploadPagesResponse{rawResponse: resp.Response()}, err
}

// UploadPagesFromURL the Upload Pages operation writes a range of pages to a page blob where the contents are read
// from a URL
//
// sourceURL is specify a URL to the copy source. sourceRange is bytes of source data in the specified range. The
// length of this range should match the ContentLength header and x-ms-range/Range destination range header.
// contentLength is the length of the request. rangeParameter is the range of bytes to which the source range would be
// written. The range should be 512 aligned and range-end is required. sourceContentMD5 is specify the md5 calculated
// for the range of bytes that must be read from the copy source. sourceContentcrc64 is specify the crc64 calculated
// for the range of bytes that must be read from the copy source. timeout is the timeout parameter is expressed in
// seconds. For more information, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
// Timeouts for Blob Service Operations.</a> encryptionKey is optional. Specifies the encryption key to use to encrypt
// the data provided in the request. If not specified, encryption is performed with the root account encryption key.
// For more information, see Encryption at Rest for Azure Storage Services. encryptionKeySha256 is the SHA-256 hash of
// the provided encryption key. Must be provided if the x-ms-encryption-key header is provided. encryptionAlgorithm is
// the algorithm used to produce the encryption key hash. Currently, the only accepted value is "AES256". Must be
// provided if the x-ms-encryption-key header is provided. encryptionScope is optional. Version 2019-07-07 and later.
// Specifies the name of the encryption scope to use to encrypt the data provided in the request. If not specified,
// encryption is performed with the default account encryption scope.  For more information, see Encryption at Rest for
// Azure Storage Services. leaseID is if specified, the operation only succeeds if the resource's lease is active and
// matches this ID. ifSequenceNumberLessThanOrEqualTo is specify this header value to operate only on a blob if it has
// a sequence number less than or equal to the specified. ifSequenceNumberLessThan is specify this header value to
// operate only on a blob if it has a sequence number less than the specified. ifSequenceNumberEqualTo is specify this
// header value to operate only on a blob if it has the specified sequence number. ifModifiedSince is specify this
// header value to operate only on a blob if it has been modified since the specified date/time. ifUnmodifiedSince is
// specify this header value to operate only on a blob if it has not been modified since the specified date/time.
// ifMatch is specify an ETag value to operate only on blobs with a matching value. ifNoneMatch is specify an ETag
// value to operate only on blobs without a matching value. ifTags is specify a SQL where clause on blob tags to
// operate only on blobs with a matching value. sourceIfModifiedSince is specify this header value to operate only on a
// blob if it has been modified since the specified date/time. sourceIfUnmodifiedSince is specify this header value to
// operate only on a blob if it has not been modified since the specified date/time. sourceIfMatch is specify an ETag
// value to operate only on blobs with a matching value. sourceIfNoneMatch is specify an ETag value to operate only on
// blobs without a matching value. requestID is provides a client-generated, opaque value with a 1 KB character limit
// that is recorded in the analytics logs when storage analytics logging is enabled. copySourceAuthorization is only
// Bearer type is supported. Credentials should be a valid OAuth access token to copy source.
func (client pageBlobClient) UploadPagesFromURL(ctx context.Context, sourceURL string, sourceRange string, contentLength int64, rangeParameter string, sourceContentMD5 []byte, sourceContentcrc64 []byte, timeout *int32, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, leaseID *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, sourceIfModifiedSince *time.Time, sourceIfUnmodifiedSince *time.Time, sourceIfMatch *ETag, sourceIfNoneMatch *ETag, requestID *string, copySourceAuthorization *string) (*PageBlobUploadPagesFromURLResponse, error) {
	if err := validate([]validation{
		{targetValue: timeout,
			constraints: []constraint{{target: "timeout", name: null, rule: false,
				chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
		return nil, err
	}
	req, err := client.uploadPagesFromURLPreparer(sourceURL, sourceRange, contentLength, rangeParameter, sourceContentMD5, sourceContentcrc64, timeout, encryptionKey, encryptionKeySha256, encryptionAlgorithm, encryptionScope, leaseID, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, ifTags, sourceIfModifiedSince, sourceIfUnmodifiedSince, sourceIfMatch, sourceIfNoneMatch, requestID, copySourceAuthorization)
	if err != nil {
		return nil, err
	}
	resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.uploadPagesFromURLResponder}, req)
	if err != nil {
		return nil, err
	}
	return resp.(*PageBlobUploadPagesFromURLResponse), err
}

// uploadPagesFromURLPreparer prepares the UploadPagesFromURL request.
func (client pageBlobClient) uploadPagesFromURLPreparer(sourceURL string, sourceRange string, contentLength int64, rangeParameter string, sourceContentMD5 []byte, sourceContentcrc64 []byte, timeout *int32, encryptionKey *string, encryptionKeySha256 *string, encryptionAlgorithm EncryptionAlgorithmType, encryptionScope *string, leaseID *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, ifTags *string, sourceIfModifiedSince *time.Time, sourceIfUnmodifiedSince *time.Time, sourceIfMatch *ETag, sourceIfNoneMatch *ETag, requestID *string, copySourceAuthorization *string) (pipeline.Request, error) {
	req, err := pipeline.NewRequest("PUT", client.url, nil)
	if err != nil {
		return req, pipeline.NewError(err, "failed to create request")
	}
	params := req.URL.Query()
	if timeout != nil {
		params.Set("timeout", strconv.FormatInt(int64(*timeout), 10))
	}
	params.Set("comp", "page")
	req.URL.RawQuery = params.Encode()
	req.Header.Set("x-ms-copy-source", sourceURL)
	req.Header.Set("x-ms-source-range", sourceRange)
	if sourceContentMD5 != nil {
		req.Header.Set("x-ms-source-content-md5", base64.StdEncoding.EncodeToString(sourceContentMD5))
	}
	if sourceContentcrc64 != nil {
		req.Header.Set("x-ms-source-content-crc64", base64.StdEncoding.EncodeToString(sourceContentcrc64))
	}
	req.Header.Set("Content-Length", strconv.FormatInt(contentLength, 10))
	req.Header.Set("x-ms-range", rangeParameter)
	if encryptionKey != nil {
		req.Header.Set("x-ms-encryption-key", *encryptionKey)
	}
	if encryptionKeySha256 != nil {
		req.Header.Set("x-ms-encryption-key-sha256", *encryptionKeySha256)
	}
	if encryptionAlgorithm != EncryptionAlgorithmNone {
		req.Header.Set("x-ms-encryption-algorithm", string(encryptionAlgorithm))
	}
	if encryptionScope != nil {
		req.Header.Set("x-ms-encryption-scope", *encryptionScope)
	}
	if leaseID != nil {
		req.Header.Set("x-ms-lease-id", *leaseID)
	}
	if ifSequenceNumberLessThanOrEqualTo != nil {
		req.Header.Set("x-ms-if-sequence-number-le", strconv.FormatInt(*ifSequenceNumberLessThanOrEqualTo, 10))
	}
	if ifSequenceNumberLessThan != nil {
		req.Header.Set("x-ms-if-sequence-number-lt", strconv.FormatInt(*ifSequenceNumberLessThan, 10))
	}
	if ifSequenceNumberEqualTo != nil {
		req.Header.Set("x-ms-if-sequence-number-eq", strconv.FormatInt(*ifSequenceNumberEqualTo, 10))
	}
	if ifModifiedSince != nil {
		req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123))
	}
	if ifUnmodifiedSince != nil {
		req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
	}
	if ifMatch != nil {
		req.Header.Set("If-Match", string(*ifMatch))
	}
	if ifNoneMatch != nil {
		req.Header.Set("If-None-Match", string(*ifNoneMatch))
	}
	if ifTags != nil {
		req.Header.Set("x-ms-if-tags", *ifTags)
	}
	if sourceIfModifiedSince != nil {
		req.Header.Set("x-ms-source-if-modified-since", (*sourceIfModifiedSince).In(gmt).Format(time.RFC1123))
	}
	if sourceIfUnmodifiedSince != nil {
		req.Header.Set("x-ms-source-if-unmodified-since", (*sourceIfUnmodifiedSince).In(gmt).Format(time.RFC1123))
	}
	if sourceIfMatch != nil {
		req.Header.Set("x-ms-source-if-match", string(*sourceIfMatch))
	}
	if sourceIfNoneMatch != nil {
		req.Header.Set("x-ms-source-if-none-match", string(*sourceIfNoneMatch))
	}
	req.Header.Set("x-ms-version", ServiceVersion)
	if requestID != nil {
		req.Header.Set("x-ms-client-request-id", *requestID)
	}
	if copySourceAuthorization != nil {
		req.Header.Set("x-ms-copy-source-authorization", *copySourceAuthorization)
	}
	req.Header.Set("x-ms-page-write", "update")
	return req, nil
}

// uploadPagesFromURLResponder handles the response to the UploadPagesFromURL request.
func (client pageBlobClient) uploadPagesFromURLResponder(resp pipeline.Response) (pipeline.Response, error) {
	err := validateResponse(resp, http.StatusOK, http.StatusCreated)
	if resp == nil {
		return nil, err
	}
	io.Copy(ioutil.Discard, resp.Response().Body)
	resp.Response().Body.Close()
	return &PageBlobUploadPagesFromURLResponse{rawResponse: resp.Response()}, err
}
