/*
Copyright 2015 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 bigtable is an API to Google Cloud Bigtable.

See https://cloud.google.com/bigtable/docs/ for general product documentation.

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


Setup and Credentials

Use NewClient or NewAdminClient to create a client that can be used to access
the data or admin APIs respectively. Both require credentials that have permission
to access the Cloud Bigtable API.

If your program is run on Google App Engine or Google Compute Engine, using the Application Default Credentials
(https://developers.google.com/accounts/docs/application-default-credentials)
is the simplest option. Those credentials will be used by default when NewClient or NewAdminClient are called.

To use alternate credentials, pass them to NewClient or NewAdminClient using option.WithTokenSource.
For instance, you can use service account credentials by visiting
https://cloud.google.com/console/project/MYPROJECT/apiui/credential,
creating a new OAuth "Client ID", storing the JSON key somewhere accessible, and writing
	jsonKey, err := ioutil.ReadFile(pathToKeyFile)
	...
	config, err := google.JWTConfigFromJSON(jsonKey, bigtable.Scope) // or bigtable.AdminScope, etc.
	...
	client, err := bigtable.NewClient(ctx, project, instance, option.WithTokenSource(config.TokenSource(ctx)))
	...
Here, `google` means the golang.org/x/oauth2/google package
and `option` means the google.golang.org/api/option package.

Reading

The principal way to read from a Bigtable is to use the ReadRows method on *Table.
A RowRange specifies a contiguous portion of a table. A Filter may be provided through
RowFilter to limit or transform the data that is returned.
	tbl := client.Open("mytable")
	...
	// Read all the rows starting with "com.google.",
	// but only fetch the columns in the "links" family.
	rr := bigtable.PrefixRange("com.google.")
	err := tbl.ReadRows(ctx, rr, func(r Row) bool {
		// do something with r
		return true // keep going
	}, bigtable.RowFilter(bigtable.FamilyFilter("links")))
	...

To read a single row, use the ReadRow helper method.
	r, err := tbl.ReadRow(ctx, "com.google.cloud") // "com.google.cloud" is the entire row key
	...

Writing

This API exposes two distinct forms of writing to a Bigtable: a Mutation and a ReadModifyWrite.
The former expresses idempotent operations.
The latter expresses non-idempotent operations and returns the new values of updated cells.
These operations are performed by creating a Mutation or ReadModifyWrite (with NewMutation or NewReadModifyWrite),
building up one or more operations on that, and then using the Apply or ApplyReadModifyWrite
methods on a Table.

For instance, to set a couple of cells in a table,
	tbl := client.Open("mytable")
	mut := bigtable.NewMutation()
	mut.Set("links", "maps.google.com", bigtable.Now(), []byte("1"))
	mut.Set("links", "golang.org", bigtable.Now(), []byte("1"))
	err := tbl.Apply(ctx, "com.google.cloud", mut)
	...

To increment an encoded value in one cell,
	tbl := client.Open("mytable")
	rmw := bigtable.NewReadModifyWrite()
	rmw.Increment("links", "golang.org", 12) // add 12 to the cell in column "links:golang.org"
	r, err := tbl.ApplyReadModifyWrite(ctx, "com.google.cloud", rmw)
	...

Retries

If a read or write operation encounters a transient error it will be retried until a successful
response, an unretryable error or the context deadline is reached. Non-idempotent writes (where
the timestamp is set to ServerTime) will not be retried. In the case of ReadRows, retried calls
will not re-scan rows that have already been processed.
*/
package bigtable // import "cloud.google.com/go/bigtable"

// Scope constants for authentication credentials.
// These should be used when using credential creation functions such as oauth.NewServiceAccountFromFile.
const (
	// Scope is the OAuth scope for Cloud Bigtable data operations.
	Scope = "https://www.googleapis.com/auth/bigtable.data"
	// ReadonlyScope is the OAuth scope for Cloud Bigtable read-only data operations.
	ReadonlyScope = "https://www.googleapis.com/auth/bigtable.readonly"

	// AdminScope is the OAuth scope for Cloud Bigtable table admin operations.
	AdminScope = "https://www.googleapis.com/auth/bigtable.admin.table"

	// InstanceAdminScope is the OAuth scope for Cloud Bigtable instance (and cluster) admin operations.
	InstanceAdminScope = "https://www.googleapis.com/auth/bigtable.admin.cluster"
)

// clientUserAgent identifies the version of this package.
// It should be bumped upon significant changes only.
const clientUserAgent = "cbt-go/20180601"

// resourcePrefixHeader is the name of the metadata header used to indicate
// the resource being operated on.
const resourcePrefixHeader = "google-cloud-resource-prefix"
