// 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 (
	"fmt"
	"log"
	"time"

	"cloud.google.com/go/datastore"
	"golang.org/x/net/context"
	"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 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").Filter("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)
	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.NewCursor.
		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}]
}
