//go:build go1.18
// +build go1.18

// 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 azcontainerregistry

import (
	"context"
	"errors"
	"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"
	"net/url"
	"strconv"
	"strings"
)

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

// CancelUpload - Cancel outstanding upload processes, releasing associated resources. If this is not called, the unfinished
// uploads will eventually timeout.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-07-01
//   - location - Link acquired from upload start or previous chunk. Note, do not include initial / (must do substring(1) )
//   - options - BlobClientCancelUploadOptions contains the optional parameters for the BlobClient.CancelUpload method.
func (client *BlobClient) CancelUpload(ctx context.Context, location string, options *BlobClientCancelUploadOptions) (BlobClientCancelUploadResponse, error) {
	var err error
	ctx, endSpan := runtime.StartSpan(ctx, "BlobClient.CancelUpload", client.internal.Tracer(), nil)
	defer func() { endSpan(err) }()
	req, err := client.cancelUploadCreateRequest(ctx, location, options)
	if err != nil {
		return BlobClientCancelUploadResponse{}, err
	}
	httpResp, err := client.internal.Pipeline().Do(req)
	if err != nil {
		return BlobClientCancelUploadResponse{}, err
	}
	if !runtime.HasStatusCode(httpResp, http.StatusNoContent) {
		err = runtime.NewResponseError(httpResp)
		return BlobClientCancelUploadResponse{}, err
	}
	return BlobClientCancelUploadResponse{}, nil
}

// cancelUploadCreateRequest creates the CancelUpload request.
func (client *BlobClient) cancelUploadCreateRequest(ctx context.Context, location string, options *BlobClientCancelUploadOptions) (*policy.Request, error) {
	urlPath := "/{nextBlobUuidLink}"
	urlPath = strings.ReplaceAll(urlPath, "{nextBlobUuidLink}", location)
	req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.endpoint, urlPath))
	if err != nil {
		return nil, err
	}
	req.Raw().Header["Accept"] = []string{"application/json"}
	return req, nil
}

// CheckBlobExists - Same as GET, except only the headers are returned.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-07-01
//   - name - Name of the image (including the namespace)
//   - digest - Digest of a BLOB
//   - options - BlobClientCheckBlobExistsOptions contains the optional parameters for the BlobClient.CheckBlobExists method.
func (client *BlobClient) CheckBlobExists(ctx context.Context, name string, digest string, options *BlobClientCheckBlobExistsOptions) (BlobClientCheckBlobExistsResponse, error) {
	var err error
	ctx, endSpan := runtime.StartSpan(ctx, "BlobClient.CheckBlobExists", client.internal.Tracer(), nil)
	defer func() { endSpan(err) }()
	req, err := client.checkBlobExistsCreateRequest(ctx, name, digest, options)
	if err != nil {
		return BlobClientCheckBlobExistsResponse{}, err
	}
	httpResp, err := client.internal.Pipeline().Do(req)
	if err != nil {
		return BlobClientCheckBlobExistsResponse{}, err
	}
	if !runtime.HasStatusCode(httpResp, http.StatusOK) {
		err = runtime.NewResponseError(httpResp)
		return BlobClientCheckBlobExistsResponse{}, err
	}
	resp, err := client.checkBlobExistsHandleResponse(httpResp)
	return resp, err
}

// checkBlobExistsCreateRequest creates the CheckBlobExists request.
func (client *BlobClient) checkBlobExistsCreateRequest(ctx context.Context, name string, digest string, options *BlobClientCheckBlobExistsOptions) (*policy.Request, error) {
	urlPath := "/v2/{name}/blobs/{digest}"
	if name == "" {
		return nil, errors.New("parameter name cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name))
	if digest == "" {
		return nil, errors.New("parameter digest cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{digest}", url.PathEscape(digest))
	req, err := runtime.NewRequest(ctx, http.MethodHead, runtime.JoinPaths(client.endpoint, urlPath))
	if err != nil {
		return nil, err
	}
	req.Raw().Header["Accept"] = []string{"application/json"}
	return req, nil
}

// checkBlobExistsHandleResponse handles the CheckBlobExists response.
func (client *BlobClient) checkBlobExistsHandleResponse(resp *http.Response) (BlobClientCheckBlobExistsResponse, error) {
	result := BlobClientCheckBlobExistsResponse{}
	if val := resp.Header.Get("Content-Length"); val != "" {
		contentLength, err := strconv.ParseInt(val, 10, 64)
		if err != nil {
			return BlobClientCheckBlobExistsResponse{}, err
		}
		result.ContentLength = &contentLength
	}
	if val := resp.Header.Get("Docker-Content-Digest"); val != "" {
		result.DockerContentDigest = &val
	}
	return result, nil
}

// CheckChunkExists - Same as GET, except only the headers are returned.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-07-01
//   - name - Name of the image (including the namespace)
//   - digest - Digest of a BLOB
//   - rangeParam - Format : bytes=-, HTTP Range header specifying blob chunk.
//   - options - BlobClientCheckChunkExistsOptions contains the optional parameters for the BlobClient.CheckChunkExists method.
func (client *BlobClient) CheckChunkExists(ctx context.Context, name string, digest string, rangeParam string, options *BlobClientCheckChunkExistsOptions) (BlobClientCheckChunkExistsResponse, error) {
	var err error
	ctx, endSpan := runtime.StartSpan(ctx, "BlobClient.CheckChunkExists", client.internal.Tracer(), nil)
	defer func() { endSpan(err) }()
	req, err := client.checkChunkExistsCreateRequest(ctx, name, digest, rangeParam, options)
	if err != nil {
		return BlobClientCheckChunkExistsResponse{}, err
	}
	httpResp, err := client.internal.Pipeline().Do(req)
	if err != nil {
		return BlobClientCheckChunkExistsResponse{}, err
	}
	if !runtime.HasStatusCode(httpResp, http.StatusOK) {
		err = runtime.NewResponseError(httpResp)
		return BlobClientCheckChunkExistsResponse{}, err
	}
	resp, err := client.checkChunkExistsHandleResponse(httpResp)
	return resp, err
}

// checkChunkExistsCreateRequest creates the CheckChunkExists request.
func (client *BlobClient) checkChunkExistsCreateRequest(ctx context.Context, name string, digest string, rangeParam string, options *BlobClientCheckChunkExistsOptions) (*policy.Request, error) {
	urlPath := "/v2/{name}/blobs/{digest}"
	if name == "" {
		return nil, errors.New("parameter name cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name))
	if digest == "" {
		return nil, errors.New("parameter digest cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{digest}", url.PathEscape(digest))
	req, err := runtime.NewRequest(ctx, http.MethodHead, runtime.JoinPaths(client.endpoint, urlPath))
	if err != nil {
		return nil, err
	}
	req.Raw().Header["Range"] = []string{rangeParam}
	req.Raw().Header["Accept"] = []string{"application/json"}
	return req, nil
}

// checkChunkExistsHandleResponse handles the CheckChunkExists response.
func (client *BlobClient) checkChunkExistsHandleResponse(resp *http.Response) (BlobClientCheckChunkExistsResponse, error) {
	result := BlobClientCheckChunkExistsResponse{}
	if val := resp.Header.Get("Content-Length"); val != "" {
		contentLength, err := strconv.ParseInt(val, 10, 64)
		if err != nil {
			return BlobClientCheckChunkExistsResponse{}, err
		}
		result.ContentLength = &contentLength
	}
	if val := resp.Header.Get("Content-Range"); val != "" {
		result.ContentRange = &val
	}
	return result, nil
}

// completeUpload - Complete the upload, providing all the data in the body, if necessary. A request without a body will just
// complete the upload with previously uploaded content.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-07-01
//   - digest - Digest of a BLOB
//   - location - Link acquired from upload start or previous chunk. Note, do not include initial / (must do substring(1) )
//   - options - BlobClientCompleteUploadOptions contains the optional parameters for the BlobClient.completeUpload method.
func (client *BlobClient) completeUpload(ctx context.Context, digest string, location string, options *BlobClientCompleteUploadOptions) (BlobClientCompleteUploadResponse, error) {
	var err error
	ctx, endSpan := runtime.StartSpan(ctx, "BlobClient.CompleteUpload", client.internal.Tracer(), nil)
	defer func() { endSpan(err) }()
	req, err := client.completeUploadCreateRequest(ctx, digest, location, options)
	if err != nil {
		return BlobClientCompleteUploadResponse{}, err
	}
	httpResp, err := client.internal.Pipeline().Do(req)
	if err != nil {
		return BlobClientCompleteUploadResponse{}, err
	}
	if !runtime.HasStatusCode(httpResp, http.StatusCreated) {
		err = runtime.NewResponseError(httpResp)
		return BlobClientCompleteUploadResponse{}, err
	}
	resp, err := client.completeUploadHandleResponse(httpResp)
	return resp, err
}

// completeUploadCreateRequest creates the completeUpload request.
func (client *BlobClient) completeUploadCreateRequest(ctx context.Context, digest string, location string, options *BlobClientCompleteUploadOptions) (*policy.Request, error) {
	urlPath := "/{nextBlobUuidLink}"
	urlPath = strings.ReplaceAll(urlPath, "{nextBlobUuidLink}", location)
	req, err := runtime.NewRequest(ctx, http.MethodPut, runtime.JoinPaths(client.endpoint, urlPath))
	if err != nil {
		return nil, err
	}
	reqQP := req.Raw().URL.Query()
	reqQP.Set("digest", digest)
	req.Raw().URL.RawQuery = reqQP.Encode()
	req.Raw().Header["Accept"] = []string{"application/json"}
	return req, nil
}

// completeUploadHandleResponse handles the completeUpload response.
func (client *BlobClient) completeUploadHandleResponse(resp *http.Response) (BlobClientCompleteUploadResponse, error) {
	result := BlobClientCompleteUploadResponse{}
	if val := resp.Header.Get("Docker-Content-Digest"); val != "" {
		result.DockerContentDigest = &val
	}
	if val := resp.Header.Get("Location"); val != "" {
		result.Location = &val
	}
	if val := resp.Header.Get("Range"); val != "" {
		result.Range = &val
	}
	return result, nil
}

// DeleteBlob - Removes an already uploaded blob.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-07-01
//   - name - Name of the image (including the namespace)
//   - digest - Digest of a BLOB
//   - options - BlobClientDeleteBlobOptions contains the optional parameters for the BlobClient.DeleteBlob method.
func (client *BlobClient) DeleteBlob(ctx context.Context, name string, digest string, options *BlobClientDeleteBlobOptions) (BlobClientDeleteBlobResponse, error) {
	var err error
	ctx, endSpan := runtime.StartSpan(ctx, "BlobClient.DeleteBlob", client.internal.Tracer(), nil)
	defer func() { endSpan(err) }()
	req, err := client.deleteBlobCreateRequest(ctx, name, digest, options)
	if err != nil {
		return BlobClientDeleteBlobResponse{}, err
	}
	httpResp, err := client.internal.Pipeline().Do(req)
	if err != nil {
		return BlobClientDeleteBlobResponse{}, err
	}
	if !runtime.HasStatusCode(httpResp, http.StatusAccepted) {
		err = runtime.NewResponseError(httpResp)
		return BlobClientDeleteBlobResponse{}, err
	}
	resp, err := client.deleteBlobHandleResponse(httpResp)
	return resp, err
}

// deleteBlobCreateRequest creates the DeleteBlob request.
func (client *BlobClient) deleteBlobCreateRequest(ctx context.Context, name string, digest string, options *BlobClientDeleteBlobOptions) (*policy.Request, error) {
	urlPath := "/v2/{name}/blobs/{digest}"
	if name == "" {
		return nil, errors.New("parameter name cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name))
	if digest == "" {
		return nil, errors.New("parameter digest cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{digest}", url.PathEscape(digest))
	req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.endpoint, urlPath))
	if err != nil {
		return nil, err
	}
	return req, nil
}

// deleteBlobHandleResponse handles the DeleteBlob response.
func (client *BlobClient) deleteBlobHandleResponse(resp *http.Response) (BlobClientDeleteBlobResponse, error) {
	result := BlobClientDeleteBlobResponse{}
	if val := resp.Header.Get("Docker-Content-Digest"); val != "" {
		result.DockerContentDigest = &val
	}
	return result, nil
}

// GetBlob - Retrieve the blob from the registry identified by digest.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-07-01
//   - name - Name of the image (including the namespace)
//   - digest - Digest of a BLOB
//   - options - BlobClientGetBlobOptions contains the optional parameters for the BlobClient.GetBlob method.
func (client *BlobClient) GetBlob(ctx context.Context, name string, digest string, options *BlobClientGetBlobOptions) (BlobClientGetBlobResponse, error) {
	var err error
	ctx, endSpan := runtime.StartSpan(ctx, "BlobClient.GetBlob", client.internal.Tracer(), nil)
	defer func() { endSpan(err) }()
	req, err := client.getBlobCreateRequest(ctx, name, digest, options)
	if err != nil {
		return BlobClientGetBlobResponse{}, err
	}
	httpResp, err := client.internal.Pipeline().Do(req)
	if err != nil {
		return BlobClientGetBlobResponse{}, err
	}
	if !runtime.HasStatusCode(httpResp, http.StatusOK) {
		err = runtime.NewResponseError(httpResp)
		return BlobClientGetBlobResponse{}, err
	}
	resp, err := client.getBlobHandleResponse(httpResp)
	return resp, err
}

// getBlobCreateRequest creates the GetBlob request.
func (client *BlobClient) getBlobCreateRequest(ctx context.Context, name string, digest string, options *BlobClientGetBlobOptions) (*policy.Request, error) {
	urlPath := "/v2/{name}/blobs/{digest}"
	if name == "" {
		return nil, errors.New("parameter name cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name))
	if digest == "" {
		return nil, errors.New("parameter digest cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{digest}", url.PathEscape(digest))
	req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.endpoint, urlPath))
	if err != nil {
		return nil, err
	}
	runtime.SkipBodyDownload(req)
	req.Raw().Header["Accept"] = []string{"application/octet-stream"}
	return req, nil
}

// getBlobHandleResponse handles the GetBlob response.
func (client *BlobClient) getBlobHandleResponse(resp *http.Response) (BlobClientGetBlobResponse, error) {
	result := BlobClientGetBlobResponse{BlobData: resp.Body}
	if val := resp.Header.Get("Content-Length"); val != "" {
		contentLength, err := strconv.ParseInt(val, 10, 64)
		if err != nil {
			return BlobClientGetBlobResponse{}, err
		}
		result.ContentLength = &contentLength
	}
	if val := resp.Header.Get("Docker-Content-Digest"); val != "" {
		result.DockerContentDigest = &val
	}
	return result, nil
}

// GetChunk - Retrieve the blob from the registry identified by digest. This endpoint may also support RFC7233 compliant range
// requests. Support can be detected by issuing a HEAD request. If the header
// Accept-Range: bytes is returned, range requests can be used to fetch partial content.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-07-01
//   - name - Name of the image (including the namespace)
//   - digest - Digest of a BLOB
//   - rangeParam - Format : bytes=-, HTTP Range header specifying blob chunk.
//   - options - BlobClientGetChunkOptions contains the optional parameters for the BlobClient.GetChunk method.
func (client *BlobClient) GetChunk(ctx context.Context, name string, digest string, rangeParam string, options *BlobClientGetChunkOptions) (BlobClientGetChunkResponse, error) {
	var err error
	ctx, endSpan := runtime.StartSpan(ctx, "BlobClient.GetChunk", client.internal.Tracer(), nil)
	defer func() { endSpan(err) }()
	req, err := client.getChunkCreateRequest(ctx, name, digest, rangeParam, options)
	if err != nil {
		return BlobClientGetChunkResponse{}, err
	}
	httpResp, err := client.internal.Pipeline().Do(req)
	if err != nil {
		return BlobClientGetChunkResponse{}, err
	}
	if !runtime.HasStatusCode(httpResp, http.StatusPartialContent) {
		err = runtime.NewResponseError(httpResp)
		return BlobClientGetChunkResponse{}, err
	}
	resp, err := client.getChunkHandleResponse(httpResp)
	return resp, err
}

// getChunkCreateRequest creates the GetChunk request.
func (client *BlobClient) getChunkCreateRequest(ctx context.Context, name string, digest string, rangeParam string, options *BlobClientGetChunkOptions) (*policy.Request, error) {
	urlPath := "/v2/{name}/blobs/{digest}"
	if name == "" {
		return nil, errors.New("parameter name cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name))
	if digest == "" {
		return nil, errors.New("parameter digest cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{digest}", url.PathEscape(digest))
	req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.endpoint, urlPath))
	if err != nil {
		return nil, err
	}
	runtime.SkipBodyDownload(req)
	req.Raw().Header["Range"] = []string{rangeParam}
	req.Raw().Header["Accept"] = []string{"application/octet-stream"}
	return req, nil
}

// getChunkHandleResponse handles the GetChunk response.
func (client *BlobClient) getChunkHandleResponse(resp *http.Response) (BlobClientGetChunkResponse, error) {
	result := BlobClientGetChunkResponse{ChunkData: resp.Body}
	if val := resp.Header.Get("Content-Length"); val != "" {
		contentLength, err := strconv.ParseInt(val, 10, 64)
		if err != nil {
			return BlobClientGetChunkResponse{}, err
		}
		result.ContentLength = &contentLength
	}
	if val := resp.Header.Get("Content-Range"); val != "" {
		result.ContentRange = &val
	}
	return result, nil
}

// GetUploadStatus - Retrieve status of upload identified by uuid. The primary purpose of this endpoint is to resolve the
// current status of a resumable upload.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-07-01
//   - location - Link acquired from upload start or previous chunk. Note, do not include initial / (must do substring(1) )
//   - options - BlobClientGetUploadStatusOptions contains the optional parameters for the BlobClient.GetUploadStatus method.
func (client *BlobClient) GetUploadStatus(ctx context.Context, location string, options *BlobClientGetUploadStatusOptions) (BlobClientGetUploadStatusResponse, error) {
	var err error
	ctx, endSpan := runtime.StartSpan(ctx, "BlobClient.GetUploadStatus", client.internal.Tracer(), nil)
	defer func() { endSpan(err) }()
	req, err := client.getUploadStatusCreateRequest(ctx, location, options)
	if err != nil {
		return BlobClientGetUploadStatusResponse{}, err
	}
	httpResp, err := client.internal.Pipeline().Do(req)
	if err != nil {
		return BlobClientGetUploadStatusResponse{}, err
	}
	if !runtime.HasStatusCode(httpResp, http.StatusNoContent) {
		err = runtime.NewResponseError(httpResp)
		return BlobClientGetUploadStatusResponse{}, err
	}
	resp, err := client.getUploadStatusHandleResponse(httpResp)
	return resp, err
}

// getUploadStatusCreateRequest creates the GetUploadStatus request.
func (client *BlobClient) getUploadStatusCreateRequest(ctx context.Context, location string, options *BlobClientGetUploadStatusOptions) (*policy.Request, error) {
	urlPath := "/{nextBlobUuidLink}"
	urlPath = strings.ReplaceAll(urlPath, "{nextBlobUuidLink}", location)
	req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.endpoint, urlPath))
	if err != nil {
		return nil, err
	}
	req.Raw().Header["Accept"] = []string{"application/json"}
	return req, nil
}

// getUploadStatusHandleResponse handles the GetUploadStatus response.
func (client *BlobClient) getUploadStatusHandleResponse(resp *http.Response) (BlobClientGetUploadStatusResponse, error) {
	result := BlobClientGetUploadStatusResponse{}
	if val := resp.Header.Get("Docker-Upload-UUID"); val != "" {
		result.DockerUploadUUID = &val
	}
	if val := resp.Header.Get("Range"); val != "" {
		result.Range = &val
	}
	return result, nil
}

// MountBlob - Mount a blob identified by the mount parameter from another repository.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-07-01
//   - name - Name of the image (including the namespace)
//   - from - Name of the source repository.
//   - mount - Digest of blob to mount from the source repository.
//   - options - BlobClientMountBlobOptions contains the optional parameters for the BlobClient.MountBlob method.
func (client *BlobClient) MountBlob(ctx context.Context, name string, from string, mount string, options *BlobClientMountBlobOptions) (BlobClientMountBlobResponse, error) {
	var err error
	ctx, endSpan := runtime.StartSpan(ctx, "BlobClient.MountBlob", client.internal.Tracer(), nil)
	defer func() { endSpan(err) }()
	req, err := client.mountBlobCreateRequest(ctx, name, from, mount, options)
	if err != nil {
		return BlobClientMountBlobResponse{}, err
	}
	httpResp, err := client.internal.Pipeline().Do(req)
	if err != nil {
		return BlobClientMountBlobResponse{}, err
	}
	if !runtime.HasStatusCode(httpResp, http.StatusCreated, http.StatusAccepted) {
		err = runtime.NewResponseError(httpResp)
		return BlobClientMountBlobResponse{}, err
	}
	resp, err := client.mountBlobHandleResponse(httpResp)
	return resp, err
}

// mountBlobCreateRequest creates the MountBlob request.
func (client *BlobClient) mountBlobCreateRequest(ctx context.Context, name string, from string, mount string, options *BlobClientMountBlobOptions) (*policy.Request, error) {
	urlPath := "/v2/{name}/blobs/uploads/"
	if name == "" {
		return nil, errors.New("parameter name cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name))
	req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.endpoint, urlPath))
	if err != nil {
		return nil, err
	}
	reqQP := req.Raw().URL.Query()
	reqQP.Set("from", from)
	reqQP.Set("mount", mount)
	req.Raw().URL.RawQuery = reqQP.Encode()
	req.Raw().Header["Accept"] = []string{"application/json"}
	return req, nil
}

// mountBlobHandleResponse handles the MountBlob response.
func (client *BlobClient) mountBlobHandleResponse(resp *http.Response) (BlobClientMountBlobResponse, error) {
	result := BlobClientMountBlobResponse{}
	if val := resp.Header.Get("Docker-Content-Digest"); val != "" {
		result.DockerContentDigest = &val
	}
	if val := resp.Header.Get("Docker-Upload-UUID"); val != "" {
		result.DockerUploadUUID = &val
	}
	if val := resp.Header.Get("Location"); val != "" {
		result.Location = &val
	}
	return result, nil
}

// StartUpload - Initiate a resumable blob upload with an empty request body.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-07-01
//   - name - Name of the image (including the namespace)
//   - options - BlobClientStartUploadOptions contains the optional parameters for the BlobClient.StartUpload method.
func (client *BlobClient) StartUpload(ctx context.Context, name string, options *BlobClientStartUploadOptions) (BlobClientStartUploadResponse, error) {
	var err error
	ctx, endSpan := runtime.StartSpan(ctx, "BlobClient.StartUpload", client.internal.Tracer(), nil)
	defer func() { endSpan(err) }()
	req, err := client.startUploadCreateRequest(ctx, name, options)
	if err != nil {
		return BlobClientStartUploadResponse{}, err
	}
	httpResp, err := client.internal.Pipeline().Do(req)
	if err != nil {
		return BlobClientStartUploadResponse{}, err
	}
	if !runtime.HasStatusCode(httpResp, http.StatusAccepted) {
		err = runtime.NewResponseError(httpResp)
		return BlobClientStartUploadResponse{}, err
	}
	resp, err := client.startUploadHandleResponse(httpResp)
	return resp, err
}

// startUploadCreateRequest creates the StartUpload request.
func (client *BlobClient) startUploadCreateRequest(ctx context.Context, name string, options *BlobClientStartUploadOptions) (*policy.Request, error) {
	urlPath := "/v2/{name}/blobs/uploads/"
	if name == "" {
		return nil, errors.New("parameter name cannot be empty")
	}
	urlPath = strings.ReplaceAll(urlPath, "{name}", url.PathEscape(name))
	req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.endpoint, urlPath))
	if err != nil {
		return nil, err
	}
	req.Raw().Header["Accept"] = []string{"application/json"}
	return req, nil
}

// startUploadHandleResponse handles the StartUpload response.
func (client *BlobClient) startUploadHandleResponse(resp *http.Response) (BlobClientStartUploadResponse, error) {
	result := BlobClientStartUploadResponse{}
	if val := resp.Header.Get("Docker-Upload-UUID"); val != "" {
		result.DockerUploadUUID = &val
	}
	if val := resp.Header.Get("Location"); val != "" {
		result.Location = &val
	}
	if val := resp.Header.Get("Range"); val != "" {
		result.Range = &val
	}
	return result, nil
}

// uploadChunk - Upload a stream of data without completing the upload.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-07-01
//   - location - Link acquired from upload start or previous chunk. Note, do not include initial / (must do substring(1) )
//   - chunkData - Raw data of blob
//   - options - blobClientUploadChunkOptions contains the optional parameters for the BlobClient.uploadChunk method.
func (client *BlobClient) uploadChunk(ctx context.Context, location string, chunkData io.ReadSeekCloser, options *blobClientUploadChunkOptions) (BlobClientUploadChunkResponse, error) {
	var err error
	ctx, endSpan := runtime.StartSpan(ctx, "BlobClient.uploadChunk", client.internal.Tracer(), nil)
	defer func() { endSpan(err) }()
	req, err := client.uploadChunkCreateRequest(ctx, location, chunkData, options)
	if err != nil {
		return BlobClientUploadChunkResponse{}, err
	}
	httpResp, err := client.internal.Pipeline().Do(req)
	if err != nil {
		return BlobClientUploadChunkResponse{}, err
	}
	if !runtime.HasStatusCode(httpResp, http.StatusAccepted) {
		err = runtime.NewResponseError(httpResp)
		return BlobClientUploadChunkResponse{}, err
	}
	resp, err := client.uploadChunkHandleResponse(httpResp)
	return resp, err
}

// uploadChunkCreateRequest creates the uploadChunk request.
func (client *BlobClient) uploadChunkCreateRequest(ctx context.Context, location string, chunkData io.ReadSeekCloser, options *blobClientUploadChunkOptions) (*policy.Request, error) {
	urlPath := "/{nextBlobUuidLink}"
	urlPath = strings.ReplaceAll(urlPath, "{nextBlobUuidLink}", location)
	req, err := runtime.NewRequest(ctx, http.MethodPatch, runtime.JoinPaths(client.endpoint, urlPath))
	if err != nil {
		return nil, err
	}
	if options != nil && options.ContentRange != nil {
		req.Raw().Header["Content-Range"] = []string{*options.ContentRange}
	}
	req.Raw().Header["Accept"] = []string{"application/json"}
	if err := req.SetBody(chunkData, "application/octet-stream"); err != nil {
		return nil, err
	}
	return req, nil
}

// uploadChunkHandleResponse handles the uploadChunk response.
func (client *BlobClient) uploadChunkHandleResponse(resp *http.Response) (BlobClientUploadChunkResponse, error) {
	result := BlobClientUploadChunkResponse{}
	if val := resp.Header.Get("Docker-Upload-UUID"); val != "" {
		result.DockerUploadUUID = &val
	}
	if val := resp.Header.Get("Location"); val != "" {
		result.Location = &val
	}
	if val := resp.Header.Get("Range"); val != "" {
		result.Range = &val
	}
	return result, nil
}
