// Copyright 2014 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 datastore_test

import (
	"context"
	"fmt"
	"log"
	"time"

	"cloud.google.com/go/datastore"
	"google.golang.org/api/iterator"
)

func ExampleNewClient() {
	ctx := context.Background()
	client, err := datastore.NewClient(ctx, "project-id")
	if err != nil {
		// TODO: Handle error.
	}
	_ = client // TODO: Use client.
}

func ExampleClient_Get() {
	ctx := context.Background()
	client, err := datastore.NewClient(ctx, "project-id")
	if err != nil {
		// TODO: Handle error.
	}

	type Article struct {
		Title       string
		Description string
		Body        string `datastore:",noindex"`
		Author      *datastore.Key
		PublishedAt time.Time
	}
	key := datastore.NameKey("Article", "articled1", nil)
	article := &Article{}
	if err := client.Get(ctx, key, article); err != nil {
		// TODO: Handle error.
	}
}

func ExampleClient_Put() {
	ctx := context.Background()
	client, err := datastore.NewClient(ctx, "project-id")
	if err != nil {
		// TODO: Handle error.
	}

	type Article struct {
		Title       string
		Description string
		Body        string `datastore:",noindex"`
		Author      *datastore.Key
		PublishedAt time.Time
	}
	newKey := datastore.IncompleteKey("Article", nil)
	_, err = client.Put(ctx, newKey, &Article{
		Title:       "The title of the article",
		Description: "The description of the article...",
		Body:        "...",
		Author:      datastore.NameKey("Author", "jbd", nil),
		PublishedAt: time.Now(),
	})
	if err != nil {
		// TODO: Handle error.
	}
}

func ExampleClient_Put_flatten() {
	ctx := context.Background()
	client, err := datastore.NewClient(ctx, "project-id")
	if err != nil {
		log.Fatal(err)
	}

	type Animal struct {
		Name  string
		Type  string
		Breed string
	}

	type Human struct {
		Name   string
		Height int
		Pet    Animal `datastore:",flatten"`
	}

	newKey := datastore.IncompleteKey("Human", nil)
	_, err = client.Put(ctx, newKey, &Human{
		Name:   "Susan",
		Height: 67,
		Pet: Animal{
			Name:  "Fluffy",
			Type:  "Cat",
			Breed: "Sphynx",
		},
	})
	if err != nil {
		log.Fatal(err)
	}
}

func ExampleClient_Delete() {
	ctx := context.Background()
	client, err := datastore.NewClient(ctx, "project-id")
	if err != nil {
		// TODO: Handle error.
	}

	key := datastore.NameKey("Article", "articled1", nil)
	if err := client.Delete(ctx, key); err != nil {
		// TODO: Handle error.
	}
}

func ExampleClient_DeleteMulti() {
	ctx := context.Background()
	client, err := datastore.NewClient(ctx, "project-id")
	if err != nil {
		// TODO: Handle error.
	}
	var keys []*datastore.Key
	for i := 1; i <= 10; i++ {
		keys = append(keys, datastore.IDKey("Article", int64(i), nil))
	}
	if err := client.DeleteMulti(ctx, keys); err != nil {
		// TODO: Handle error.
	}
}

type Post struct {
	Title       string
	PublishedAt time.Time
	Comments    int
}

func ExampleClient_GetMulti() {
	ctx := context.Background()
	client, err := datastore.NewClient(ctx, "project-id")
	if err != nil {
		// TODO: Handle error.
	}

	keys := []*datastore.Key{
		datastore.NameKey("Post", "post1", nil),
		datastore.NameKey("Post", "post2", nil),
		datastore.NameKey("Post", "post3", nil),
	}
	posts := make([]Post, 3)
	if err := client.GetMulti(ctx, keys, posts); err != nil {
		// TODO: Handle error.
	}
}

func ExampleMultiError() {
	ctx := context.Background()
	client, err := datastore.NewClient(ctx, "project-id")
	if err != nil {
		// TODO: Handle error.
	}

	keys := []*datastore.Key{
		datastore.NameKey("bad-key", "bad-key", nil),
	}
	posts := make([]Post, 1)
	if err := client.GetMulti(ctx, keys, posts); err != nil {
		if merr, ok := err.(datastore.MultiError); ok {
			for _, err := range merr {
				// TODO: Handle error.
				_ = err
			}
		} else {
			// TODO: Handle error.
		}
	}
}

func ExampleClient_PutMulti_slice() {
	ctx := context.Background()
	client, err := datastore.NewClient(ctx, "project-id")
	if err != nil {
		// TODO: Handle error.
	}

	keys := []*datastore.Key{
		datastore.NameKey("Post", "post1", nil),
		datastore.NameKey("Post", "post2", nil),
	}

	// PutMulti with a Post slice.
	posts := []*Post{
		{Title: "Post 1", PublishedAt: time.Now()},
		{Title: "Post 2", PublishedAt: time.Now()},
	}
	if _, err := client.PutMulti(ctx, keys, posts); err != nil {
		// TODO: Handle error.
	}
}

func ExampleClient_PutMulti_interfaceSlice() {
	ctx := context.Background()
	client, err := datastore.NewClient(ctx, "project-id")
	if err != nil {
		// TODO: Handle error.
	}

	keys := []*datastore.Key{
		datastore.NameKey("Post", "post1", nil),
		datastore.NameKey("Post", "post2", nil),
	}

	// PutMulti with an empty interface slice.
	posts := []interface{}{
		&Post{Title: "Post 1", PublishedAt: time.Now()},
		&Post{Title: "Post 2", PublishedAt: time.Now()},
	}
	if _, err := client.PutMulti(ctx, keys, posts); err != nil {
		// TODO: Handle error.
	}
}

func ExampleNewQuery() {
	// Query for Post entities.
	q := datastore.NewQuery("Post")
	_ = q // TODO: Use the query with Client.Run.
}

func ExampleNewQuery_options() {
	// Query to order the posts by the number of comments they have received.
	q := datastore.NewQuery("Post").Order("-Comments")
	// Start listing from an offset and limit the results.
	q = q.Offset(20).Limit(10)
	_ = q // TODO: Use the query.
}

func ExampleClient_Count() {
	ctx := context.Background()
	client, err := datastore.NewClient(ctx, "project-id")
	if err != nil {
		// TODO: Handle error.
	}
	// Count the number of the post entities.
	q := datastore.NewQuery("Post")
	n, err := client.Count(ctx, q)
	if err != nil {
		// TODO: Handle error.
	}
	fmt.Printf("There are %d posts.", n)
}

func ExampleClient_Run() {
	ctx := context.Background()
	client, err := datastore.NewClient(ctx, "project-id")
	if err != nil {
		// TODO: Handle error.
	}
	// List the posts published since yesterday.
	yesterday := time.Now().Add(-24 * time.Hour)
	q := datastore.NewQuery("Post").FilterField("PublishedAt", ">", yesterday)
	it := client.Run(ctx, q)
	_ = it // TODO: iterate using Next.
}

func ExampleClient_NewTransaction() {
	ctx := context.Background()
	client, err := datastore.NewClient(ctx, "project-id")
	if err != nil {
		// TODO: Handle error.
	}
	const retries = 3

	// Increment a counter.
	// See https://cloud.google.com/appengine/articles/sharding_counters for
	// a more scalable solution.
	type Counter struct {
		Count int
	}

	key := datastore.NameKey("counter", "CounterA", nil)
	var tx *datastore.Transaction
	for i := 0; i < retries; i++ {
		tx, err = client.NewTransaction(ctx)
		if err != nil {
			break
		}

		var c Counter
		if err = tx.Get(key, &c); err != nil && err != datastore.ErrNoSuchEntity {
			break
		}
		c.Count++
		if _, err = tx.Put(key, &c); err != nil {
			break
		}

		// Attempt to commit the transaction. If there's a conflict, try again.
		if _, err = tx.Commit(); err != datastore.ErrConcurrentTransaction {
			break
		}
	}
	if err != nil {
		// TODO: Handle error.
	}
}

func ExampleClient_RunInTransaction() {
	ctx := context.Background()
	client, err := datastore.NewClient(ctx, "project-id")
	if err != nil {
		// TODO: Handle error.
	}

	// Increment a counter.
	// See https://cloud.google.com/appengine/articles/sharding_counters for
	// a more scalable solution.
	type Counter struct {
		Count int
	}

	var count int
	key := datastore.NameKey("Counter", "singleton", nil)
	_, err = client.RunInTransaction(ctx, func(tx *datastore.Transaction) error {
		var x Counter
		if err := tx.Get(key, &x); err != nil && err != datastore.ErrNoSuchEntity {
			return err
		}
		x.Count++
		if _, err := tx.Put(key, &x); err != nil {
			return err
		}
		count = x.Count
		return nil
	})
	if err != nil {
		// TODO: Handle error.
	}
	// The value of count is only valid once the transaction is successful
	// (RunInTransaction has returned nil).
	fmt.Printf("Count=%d\n", count)
}

func ExampleClient_AllocateIDs() {
	ctx := context.Background()
	client, err := datastore.NewClient(ctx, "project-id")
	if err != nil {
		// TODO: Handle error.
	}
	var keys []*datastore.Key
	for i := 0; i < 10; i++ {
		keys = append(keys, datastore.IncompleteKey("Article", nil))
	}
	keys, err = client.AllocateIDs(ctx, keys)
	if err != nil {
		// TODO: Handle error.
	}
	_ = keys // TODO: Use keys.
}

func ExampleKey_Encode() {
	key := datastore.IDKey("Article", 1, nil)
	encoded := key.Encode()
	fmt.Println(encoded)
	// Output: EgsKB0FydGljbGUQAQ
}

func ExampleDecodeKey() {
	const encoded = "EgsKB0FydGljbGUQAQ"
	key, err := datastore.DecodeKey(encoded)
	if err != nil {
		// TODO: Handle error.
	}
	fmt.Println(key)
	// Output: /Article,1
}

func ExampleIDKey() {
	// Key with numeric ID.
	k := datastore.IDKey("Article", 1, nil)
	_ = k // TODO: Use key.
}

func ExampleNameKey() {
	// Key with string ID.
	k := datastore.NameKey("Article", "article8", nil)
	_ = k // TODO: Use key.
}

func ExampleIncompleteKey() {
	k := datastore.IncompleteKey("Article", nil)
	_ = k // TODO: Use incomplete key.
}

func ExampleClient_GetAll() {
	ctx := context.Background()
	client, err := datastore.NewClient(ctx, "project-id")
	if err != nil {
		// TODO: Handle error.
	}
	var posts []*Post
	keys, err := client.GetAll(ctx, datastore.NewQuery("Post"), &posts)
	if err != nil {
		// TODO: Handle error.
	}
	for i, key := range keys {
		fmt.Println(key)
		fmt.Println(posts[i])
	}
}

func ExampleClient_Mutate() {
	ctx := context.Background()
	client, err := datastore.NewClient(ctx, "project-id")
	if err != nil {
		// TODO: Handle error.
	}

	key1 := datastore.NameKey("Post", "post1", nil)
	key2 := datastore.NameKey("Post", "post2", nil)
	key3 := datastore.NameKey("Post", "post3", nil)
	key4 := datastore.NameKey("Post", "post4", nil)

	_, err = client.Mutate(ctx,
		datastore.NewInsert(key1, Post{Title: "Post 1"}),
		datastore.NewUpsert(key2, Post{Title: "Post 2"}),
		datastore.NewUpdate(key3, Post{Title: "Post 3"}),
		datastore.NewDelete(key4))
	if err != nil {
		// TODO: Handle error.
	}
}

func ExampleCommit_Key() {
	ctx := context.Background()
	client, err := datastore.NewClient(ctx, "")
	if err != nil {
		// TODO: Handle error.
	}
	var pk1, pk2 *datastore.PendingKey
	// Create two posts in a single transaction.
	commit, err := client.RunInTransaction(ctx, func(tx *datastore.Transaction) error {
		var err error
		pk1, err = tx.Put(datastore.IncompleteKey("Post", nil), &Post{Title: "Post 1", PublishedAt: time.Now()})
		if err != nil {
			return err
		}
		pk2, err = tx.Put(datastore.IncompleteKey("Post", nil), &Post{Title: "Post 2", PublishedAt: time.Now()})
		if err != nil {
			return err
		}
		return nil
	})
	if err != nil {
		// TODO: Handle error.
	}
	// Now pk1, pk2 are valid PendingKeys. Let's convert them into real keys
	// using the Commit object.
	k1 := commit.Key(pk1)
	k2 := commit.Key(pk2)
	fmt.Println(k1, k2)
}

func ExampleIterator_Next() {
	ctx := context.Background()
	client, err := datastore.NewClient(ctx, "project-id")
	if err != nil {
		// TODO: Handle error.
	}
	it := client.Run(ctx, datastore.NewQuery("Post"))
	for {
		var p Post
		key, err := it.Next(&p)
		if err == iterator.Done {
			break
		}
		if err != nil {
			// TODO: Handle error.
		}
		fmt.Println(key, p)
	}
}

func ExampleIterator_Cursor() {
	ctx := context.Background()
	client, err := datastore.NewClient(ctx, "project-id")
	if err != nil {
		// TODO: Handle error.
	}
	it := client.Run(ctx, datastore.NewQuery("Post"))
	for {
		var p Post
		_, err := it.Next(&p)
		if err == iterator.Done {
			break
		}
		if err != nil {
			// TODO: Handle error.
		}
		fmt.Println(p)
		cursor, err := it.Cursor()
		if err != nil {
			// TODO: Handle error.
		}
		// When printed, a cursor will display as a string that can be passed
		// to datastore.DecodeCursor.
		fmt.Printf("to resume with this post, use cursor %s\n", cursor)
	}
}

func ExampleDecodeCursor() {
	// See Query.Start for a fuller example of DecodeCursor.
	// getCursor represents a function that returns a cursor from a previous
	// iteration in string form.
	cursorString := getCursor()
	cursor, err := datastore.DecodeCursor(cursorString)
	if err != nil {
		// TODO: Handle error.
	}
	_ = cursor // TODO: Use the cursor with Query.Start or Query.End.
}

func getCursor() string { return "" }

func ExampleQuery_Start() {
	// This example demonstrates how to use cursors and Query.Start
	// to resume an iteration.
	ctx := context.Background()
	client, err := datastore.NewClient(ctx, "project-id")
	if err != nil {
		// TODO: Handle error.
	}
	// getCursor represents a function that returns a cursor from a previous
	// iteration in string form.
	cursorString := getCursor()
	cursor, err := datastore.DecodeCursor(cursorString)
	if err != nil {
		// TODO: Handle error.
	}
	it := client.Run(ctx, datastore.NewQuery("Post").Start(cursor))
	_ = it // TODO: Use iterator.
}

func ExampleLoadStruct() {
	type Player struct {
		User  string
		Score int
	}
	// Normally LoadStruct would only be used inside a custom implementation of
	// PropertyLoadSaver; this is for illustrative purposes only.
	props := []datastore.Property{
		{Name: "User", Value: "Alice"},
		{Name: "Score", Value: int64(97)},
	}

	var p Player
	if err := datastore.LoadStruct(&p, props); err != nil {
		// TODO: Handle error.
	}
	fmt.Println(p)
	// Output: {Alice 97}
}

func ExampleSaveStruct() {
	type Player struct {
		User  string
		Score int
	}

	p := &Player{
		User:  "Alice",
		Score: 97,
	}
	props, err := datastore.SaveStruct(p)
	if err != nil {
		// TODO: Handle error.
	}
	fmt.Println(props)
	// TODO(jba): make this output stable: Output: [{User Alice false} {Score 97 false}]
}
