// Copyright 2016 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/*
Package storage provides an easy way to work with Google Cloud Storage.
Google Cloud Storage stores data in named objects, which are grouped into buckets.

More information about Google Cloud Storage is available at
https://cloud.google.com/storage/docs.

See https://pkg.go.dev/cloud.google.com/go for authentication, timeouts,
connection pooling and similar aspects of this package.

# Creating a Client

To start working with this package, create a [Client]:

	ctx := context.Background()
	client, err := storage.NewClient(ctx)
	if err != nil {
	    // TODO: Handle error.
	}

The client will use your default application credentials. Clients should be
reused instead of created as needed. The methods of [Client] are safe for
concurrent use by multiple goroutines.

You may configure the client by passing in options from the [google.golang.org/api/option]
package. You may also use options defined in this package, such as [WithJSONReads].

If you only wish to access public data, you can create
an unauthenticated client with

	client, err := storage.NewClient(ctx, option.WithoutAuthentication())

To use an emulator with this library, you can set the STORAGE_EMULATOR_HOST
environment variable to the address at which your emulator is running. This will
send requests to that address instead of to Cloud Storage. You can then create
and use a client as usual:

	// Set STORAGE_EMULATOR_HOST environment variable.
	err := os.Setenv("STORAGE_EMULATOR_HOST", "localhost:9000")
	if err != nil {
	    // TODO: Handle error.
	}

	// Create client as usual.
	client, err := storage.NewClient(ctx)
	if err != nil {
	    // TODO: Handle error.
	}

	// This request is now directed to http://localhost:9000/storage/v1/b
	// instead of https://storage.googleapis.com/storage/v1/b
	if err := client.Bucket("my-bucket").Create(ctx, projectID, nil); err != nil {
	    // TODO: Handle error.
	}

Please note that there is no official emulator for Cloud Storage.

# Buckets

A Google Cloud Storage bucket is a collection of objects. To work with a
bucket, make a bucket handle:

	bkt := client.Bucket(bucketName)

A handle is a reference to a bucket. You can have a handle even if the
bucket doesn't exist yet. To create a bucket in Google Cloud Storage,
call [BucketHandle.Create]:

	if err := bkt.Create(ctx, projectID, nil); err != nil {
	    // TODO: Handle error.
	}

Note that although buckets are associated with projects, bucket names are
global across all projects.

Each bucket has associated metadata, represented in this package by
[BucketAttrs]. The third argument to [BucketHandle.Create] allows you to set
the initial [BucketAttrs] of a bucket. To retrieve a bucket's attributes, use
[BucketHandle.Attrs]:

	attrs, err := bkt.Attrs(ctx)
	if err != nil {
	    // TODO: Handle error.
	}
	fmt.Printf("bucket %s, created at %s, is located in %s with storage class %s\n",
	    attrs.Name, attrs.Created, attrs.Location, attrs.StorageClass)

# Objects

An object holds arbitrary data as a sequence of bytes, like a file. You
refer to objects using a handle, just as with buckets, but unlike buckets
you don't explicitly create an object. Instead, the first time you write
to an object it will be created. You can use the standard Go [io.Reader]
and [io.Writer] interfaces to read and write object data:

	obj := bkt.Object("data")
	// Write something to obj.
	// w implements io.Writer.
	w := obj.NewWriter(ctx)
	// Write some text to obj. This will either create the object or overwrite whatever is there already.
	if _, err := fmt.Fprintf(w, "This object contains text.\n"); err != nil {
	    // TODO: Handle error.
	}
	// Close, just like writing a file.
	if err := w.Close(); err != nil {
	    // TODO: Handle error.
	}

	// Read it back.
	r, err := obj.NewReader(ctx)
	if err != nil {
	    // TODO: Handle error.
	}
	defer r.Close()
	if _, err := io.Copy(os.Stdout, r); err != nil {
	    // TODO: Handle error.
	}
	// Prints "This object contains text."

Objects also have attributes, which you can fetch with [ObjectHandle.Attrs]:

	objAttrs, err := obj.Attrs(ctx)
	if err != nil {
	    // TODO: Handle error.
	}
	fmt.Printf("object %s has size %d and can be read using %s\n",
	    objAttrs.Name, objAttrs.Size, objAttrs.MediaLink)

# Listing objects

Listing objects in a bucket is done with the [BucketHandle.Objects] method:

	query := &storage.Query{Prefix: ""}

	var names []string
	it := bkt.Objects(ctx, query)
	for {
	    attrs, err := it.Next()
	    if err == iterator.Done {
	        break
	    }
	    if err != nil {
	        log.Fatal(err)
	    }
	    names = append(names, attrs.Name)
	}

Objects are listed lexicographically by name. To filter objects
lexicographically, [Query.StartOffset] and/or [Query.EndOffset] can be used:

	query := &storage.Query{
	    Prefix: "",
	    StartOffset: "bar/",  // Only list objects lexicographically >= "bar/"
	    EndOffset: "foo/",    // Only list objects lexicographically < "foo/"
	}

	// ... as before

If only a subset of object attributes is needed when listing, specifying this
subset using [Query.SetAttrSelection] may speed up the listing process:

	query := &storage.Query{Prefix: ""}
	query.SetAttrSelection([]string{"Name"})

	// ... as before

# ACLs

Both objects and buckets have ACLs (Access Control Lists). An ACL is a list of
ACLRules, each of which specifies the role of a user, group or project. ACLs
are suitable for fine-grained control, but you may prefer using IAM to control
access at the project level (see [Cloud Storage IAM docs].

To list the ACLs of a bucket or object, obtain an [ACLHandle] and call [ACLHandle.List]:

	acls, err := obj.ACL().List(ctx)
	if err != nil {
	    // TODO: Handle error.
	}
	for _, rule := range acls {
	    fmt.Printf("%s has role %s\n", rule.Entity, rule.Role)
	}

You can also set and delete ACLs.

# Conditions

Every object has a generation and a metageneration. The generation changes
whenever the content changes, and the metageneration changes whenever the
metadata changes. [Conditions] let you check these values before an operation;
the operation only executes if the conditions match. You can use conditions to
prevent race conditions in read-modify-write operations.

For example, say you've read an object's metadata into objAttrs. Now
you want to write to that object, but only if its contents haven't changed
since you read it. Here is how to express that:

	w = obj.If(storage.Conditions{GenerationMatch: objAttrs.Generation}).NewWriter(ctx)
	// Proceed with writing as above.

# Signed URLs

You can obtain a URL that lets anyone read or write an object for a limited time.
Signing a URL requires credentials authorized to sign a URL. To use the same
authentication that was used when instantiating the Storage client, use
[BucketHandle.SignedURL].

	url, err := client.Bucket(bucketName).SignedURL(objectName, opts)
	if err != nil {
	    // TODO: Handle error.
	}
	fmt.Println(url)

You can also sign a URL without creating a client. See the documentation of
[SignedURL] for details.

	url, err := storage.SignedURL(bucketName, "shared-object", opts)
	if err != nil {
	    // TODO: Handle error.
	}
	fmt.Println(url)

# Post Policy V4 Signed Request

A type of signed request that allows uploads through HTML forms directly to Cloud Storage with
temporary permission. Conditions can be applied to restrict how the HTML form is used and exercised
by a user.

For more information, please see the [XML POST Object docs] as well
as the documentation of [BucketHandle.GenerateSignedPostPolicyV4].

	pv4, err := client.Bucket(bucketName).GenerateSignedPostPolicyV4(objectName, opts)
	if err != nil {
	    // TODO: Handle error.
	}
	fmt.Printf("URL: %s\nFields; %v\n", pv4.URL, pv4.Fields)

# Credential requirements for signing

If the GoogleAccessID and PrivateKey option fields are not provided, they will
be automatically detected by [BucketHandle.SignedURL] and
[BucketHandle.GenerateSignedPostPolicyV4] if any of the following are true:
  - you are authenticated to the Storage Client with a service account's
    downloaded private key, either directly in code or by setting the
    GOOGLE_APPLICATION_CREDENTIALS environment variable (see [Other Environments]),
  - your application is running on Google Compute Engine (GCE), or
  - you are logged into [gcloud using application default credentials]
    with [impersonation enabled].

Detecting GoogleAccessID may not be possible if you are authenticated using a
token source or using [option.WithHTTPClient]. In this case, you can provide a
service account email for GoogleAccessID and the client will attempt to sign
the URL or Post Policy using that service account.

To generate the signature, you must have:
  - iam.serviceAccounts.signBlob permissions on the GoogleAccessID service
    account, and
  - the [IAM Service Account Credentials API] enabled (unless authenticating
    with a downloaded private key).

# Errors

Errors returned by this client are often of the type [googleapi.Error].
These errors can be introspected for more information by using [errors.As]
with the richer [googleapi.Error] type. For example:

	var e *googleapi.Error
	if ok := errors.As(err, &e); ok {
		  if e.Code == 409 { ... }
	}

# Retrying failed requests

Methods in this package may retry calls that fail with transient errors.
Retrying continues indefinitely unless the controlling context is canceled, the
client is closed, or a non-transient error is received. To stop retries from
continuing, use context timeouts or cancellation.

The retry strategy in this library follows best practices for Cloud Storage. By
default, operations are retried only if they are idempotent, and exponential
backoff with jitter is employed. In addition, errors are only retried if they
are defined as transient by the service. See the [Cloud Storage retry docs]
for more information.

Users can configure non-default retry behavior for a single library call (using
[BucketHandle.Retryer] and [ObjectHandle.Retryer]) or for all calls made by a
client (using [Client.SetRetry]). For example:

	o := client.Bucket(bucket).Object(object).Retryer(
		// Use WithBackoff to change the timing of the exponential backoff.
		storage.WithBackoff(gax.Backoff{
			Initial:    2 * time.Second,
		}),
		// Use WithPolicy to configure the idempotency policy. RetryAlways will
		// retry the operation even if it is non-idempotent.
		storage.WithPolicy(storage.RetryAlways),
	)

	// Use a context timeout to set an overall deadline on the call, including all
	// potential retries.
	ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
	defer cancel()

	// Delete an object using the specified strategy and timeout.
	if err := o.Delete(ctx); err != nil {
		// Handle err.
	}

# Sending Custom Headers

You can add custom headers to any API call made by this package by using
[callctx.SetHeaders] on the context which is passed to the method. For example,
to add a [custom audit logging] header:

	ctx := context.Background()
	ctx = callctx.SetHeaders(ctx, "x-goog-custom-audit-<key>", "<value>")
	// Use client as usual with the context and the additional headers will be sent.
	client.Bucket("my-bucket").Attrs(ctx)

# Experimental gRPC API

This package includes support for the Cloud Storage gRPC API, which is currently
in preview. This implementation uses gRPC rather than the current JSON & XML
APIs to make requests to Cloud Storage. Kindly contact the Google Cloud Storage gRPC
team at gcs-grpc-contact@google.com with a list of GCS buckets you would like to
allowlist to access this API. The Go Storage gRPC library is not yet generally
available, so it may be subject to breaking changes.

To create a client which will use gRPC, use the alternate constructor:

	ctx := context.Background()
	client, err := storage.NewGRPCClient(ctx)
	if err != nil {
		// TODO: Handle error.
	}
	// Use client as usual.

If the application is running within GCP, users may get better performance by
enabling Direct Google Access (enabling requests to skip some proxy steps). To enable,
set the environment variable `GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS=true` and add
the following side-effect imports to your application:

	import (
		_ "google.golang.org/grpc/balancer/rls"
		_ "google.golang.org/grpc/xds/googledirectpath"
	)

# Storage Control API

Certain control plane and long-running operations for Cloud Storage (including Folder
and Managed Folder operations) are supported via the autogenerated Storage Control
client, which is available as a subpackage in this module. See package docs at
[cloud.google.com/go/storage/control/apiv2] or reference the [Storage Control API] docs.

[Cloud Storage IAM docs]: https://cloud.google.com/storage/docs/access-control/iam
[XML POST Object docs]: https://cloud.google.com/storage/docs/xml-api/post-object
[Cloud Storage retry docs]: https://cloud.google.com/storage/docs/retry-strategy
[Other Environments]: https://cloud.google.com/storage/docs/authentication#libauth
[gcloud using application default credentials]: https://cloud.google.com/sdk/gcloud/reference/auth/application-default/login
[impersonation enabled]: https://cloud.google.com/sdk/gcloud/reference#--impersonate-service-account
[IAM Service Account Credentials API]: https://console.developers.google.com/apis/api/iamcredentials.googleapis.com/overview
[custom audit logging]: https://cloud.google.com/storage/docs/audit-logging#add-custom-metadata
[Storage Control API]: https://cloud.google.com/storage/docs/reference/rpc/google.storage.control.v2
*/
package storage // import "cloud.google.com/go/storage"
