// Copyright 2017 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 internal

// TODO(deklerk) can this file and directory be deleted, or is it being used for documentation somewhere?

import (
	"context"
	"fmt"

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

// State represents a state.
//[ structDef
type State struct {
	Capital    string  `firestore:"capital"`
	Population float64 `firestore:"pop"` // in millions
}

//]

func f1() {
	//[ NewClient
	ctx := context.Background()
	client, err := firestore.NewClient(ctx, "projectID")
	if err != nil {
		// TODO: Handle error.
	}
	//]
	//[ refs
	states := client.Collection("States")
	ny := states.Doc("NewYork")
	// Or, in a single call:
	ny = client.Doc("States/NewYork")
	//]
	//[ docref.Get
	docsnap, err := ny.Get(ctx)
	if err != nil {
		// TODO: Handle error.
	}
	dataMap := docsnap.Data()
	fmt.Println(dataMap)
	//]
	//[ DataTo
	var nyData State
	if err := docsnap.DataTo(&nyData); err != nil {
		// TODO: Handle error.
	}
	//]
	//[ GetAll
	docsnaps, err := client.GetAll(ctx, []*firestore.DocumentRef{
		states.Doc("Wisconsin"), states.Doc("Ohio"),
	})
	if err != nil {
		// TODO: Handle error.
	}
	for _, ds := range docsnaps {
		_ = ds // TODO: Use ds.
	}
	//[ docref.Create
	wr, err := ny.Create(ctx, State{
		Capital:    "Albany",
		Population: 19.8,
	})
	if err != nil {
		// TODO: Handle error.
	}
	fmt.Println(wr)
	//]
	//[ docref.Set
	ca := states.Doc("California")
	_, err = ca.Set(ctx, State{
		Capital:    "Sacramento",
		Population: 39.14,
	})
	//]

	//[ docref.Update
	_, err = ca.Update(ctx, []firestore.Update{{Path: "capital", Value: "Sacramento"}})
	//]

	//[ docref.Delete
	_, err = ny.Delete(ctx)
	//]

	//[ LUT-precond
	docsnap, err = ca.Get(ctx)
	if err != nil {
		// TODO: Handle error.
	}
	_, err = ca.Update(ctx,
		[]firestore.Update{{Path: "capital", Value: "Sacramento"}},
		firestore.LastUpdateTime(docsnap.UpdateTime))
	//]

	//[ WriteBatch
	writeResults, err := client.Batch().
		Create(ny, State{Capital: "Albany"}).
		Update(ca, []firestore.Update{{Path: "capital", Value: "Sacramento"}}).
		Delete(client.Doc("States/WestDakota")).
		Commit(ctx)
	//]
	_ = writeResults

	//[ Query
	q := states.Where("pop", ">", 10).OrderBy("pop", firestore.Desc)
	//]
	//[ Documents
	iter := q.Documents(ctx)
	for {
		doc, err := iter.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			// TODO: Handle error.
		}
		fmt.Println(doc.Data())
	}
	//]

	//[ CollQuery
	iter = client.Collection("States").Documents(ctx)
	//]
}

func txn() {
	var ctx context.Context
	var client *firestore.Client
	//[ Transaction
	ny := client.Doc("States/NewYork")
	err := client.RunTransaction(ctx, func(ctx context.Context, tx *firestore.Transaction) error {
		doc, err := tx.Get(ny) // tx.Get, NOT ny.Get!
		if err != nil {
			return err
		}
		pop, err := doc.DataAt("pop")
		if err != nil {
			return err
		}
		return tx.Update(ny, []firestore.Update{{Path: "pop", Value: pop.(float64) + 0.2}})
	})
	if err != nil {
		// TODO: Handle error.
	}
	//]
}
