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

package pageblob_test

import (
	"bytes"
	"context"
	"crypto/rand"
	"fmt"
	"log"
	"os"

	"github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming"
	"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/pageblob"
)

func handleError(err error) {
	if err != nil {
		log.Fatal(err.Error())
	}
}

// ExamplePageBlobClient shows how to manipulate a page blob with PageBlobClient.
// A page blob is a collection of 512-byte pages optimized for random read and write operations.
// The maximum size for a page blob is 8 TB.
func Example_pageblob_Client() {
	accountName, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_NAME")
	if !ok {
		panic("AZURE_STORAGE_ACCOUNT_NAME could not be found")
	}
	blobName := "test_page_blob.vhd"
	blobURL := fmt.Sprintf("https://%s.blob.core.windows.net/testcontainer/%s", accountName, blobName)

	cred, err := azidentity.NewDefaultAzureCredential(nil)
	handleError(err)

	pageBlobClient, err := pageblob.NewClient(blobURL, cred, nil)
	handleError(err)

	_, err = pageBlobClient.Create(context.TODO(), pageblob.PageBytes*4, nil)
	handleError(err)

	// Upload 5 pages to the page blob
	for i := 0; i < 5; i++ {
		count := int64(1024)
		page := make([]byte, 2*pageblob.PageBytes)
		_, err := rand.Read(page)
		if err != nil {
			return
		}
		_, err = pageBlobClient.UploadPages(context.Background(), streaming.NopCloser(bytes.NewReader(page)),
			blob.HTTPRange{Offset: int64(i) * count, Count: count}, nil)
		handleError(err)
	}

	pager := pageBlobClient.NewGetPageRangesPager(&pageblob.GetPageRangesOptions{
		Range: blob.HTTPRange{
			Count: int64(10 * pageblob.PageBytes),
		},
	})

	for pager.More() {
		resp, err := pager.NextPage(context.TODO())
		if err != nil {
			log.Fatal(err)
		}
		for _, pr := range resp.PageList.PageRange {
			fmt.Printf("Start=%d, End=%d\n", pr.Start, pr.End)
		}
	}

	get, err := pageBlobClient.DownloadStream(context.TODO(), nil)
	handleError(err)
	blobData := &bytes.Buffer{}
	reader := get.Body
	_, err = blobData.ReadFrom(reader)
	if err != nil {
		return
	}
	err = reader.Close()
	if err != nil {
		return
	}
	fmt.Println(blobData.String())
}
