// Copyright 2014 Google Inc. All Rights Reserved.
//
// 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 recieved.
	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 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}]
}
