// Copyright 2018 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

import (
	"testing"

	"cloud.google.com/go/internal/testutil"
	pb "google.golang.org/genproto/googleapis/datastore/v1"
)

func TestMutationProtos(t *testing.T) {
	var keys []*Key
	for i := 1; i <= 4; i++ {
		k := IDKey("kind", int64(i), nil)
		keys = append(keys, k)
	}
	entity := &PropertyList{{Name: "n", Value: "v"}}
	entityForKey := func(k *Key) *pb.Entity {
		return &pb.Entity{
			Key: keyToProto(k),
			Properties: map[string]*pb.Value{
				"n": &pb.Value{ValueType: &pb.Value_StringValue{StringValue: "v"}},
			},
		}
	}
	for _, test := range []struct {
		desc string
		in   []*Mutation
		want []*pb.Mutation
	}{
		{
			desc: "nil",
			in:   nil,
			want: nil,
		},
		{
			desc: "empty",
			in:   []*Mutation{},
			want: nil,
		},
		{
			desc: "various",
			in: []*Mutation{
				NewInsert(keys[0], entity),
				NewUpsert(keys[1], entity),
				NewUpdate(keys[2], entity),
				NewDelete(keys[3]),
			},
			want: []*pb.Mutation{
				&pb.Mutation{Operation: &pb.Mutation_Insert{Insert: entityForKey(keys[0])}},
				&pb.Mutation{Operation: &pb.Mutation_Upsert{Upsert: entityForKey(keys[1])}},
				&pb.Mutation{Operation: &pb.Mutation_Update{Update: entityForKey(keys[2])}},
				&pb.Mutation{Operation: &pb.Mutation_Delete{Delete: keyToProto(keys[3])}},
			},
		},
		{
			desc: "duplicate deletes",
			in: []*Mutation{
				NewDelete(keys[0]),
				NewInsert(keys[1], entity),
				NewDelete(keys[0]),
				NewDelete(keys[2]),
				NewDelete(keys[0]),
			},
			want: []*pb.Mutation{
				&pb.Mutation{Operation: &pb.Mutation_Delete{Delete: keyToProto(keys[0])}},
				&pb.Mutation{Operation: &pb.Mutation_Insert{Insert: entityForKey(keys[1])}},
				&pb.Mutation{Operation: &pb.Mutation_Delete{Delete: keyToProto(keys[2])}},
			},
		},
	} {
		got, err := mutationProtos(test.in)
		if err != nil {
			t.Errorf("%s: %v", test.desc, err)
			continue
		}
		if diff := testutil.Diff(got, test.want); diff != "" {
			t.Errorf("%s: %s", test.desc, diff)
		}
	}
}

func TestMutationProtosErrors(t *testing.T) {
	entity := &PropertyList{{Name: "n", Value: "v"}}
	k := IDKey("kind", 1, nil)
	ik := IncompleteKey("kind", nil)
	for _, test := range []struct {
		desc string
		in   []*Mutation
		want []int // non-nil indexes of MultiError
	}{
		{
			desc: "invalid key",
			in: []*Mutation{
				NewInsert(nil, entity),
				NewUpdate(nil, entity),
				NewUpsert(nil, entity),
				NewDelete(nil),
			},
			want: []int{0, 1, 2, 3},
		},
		{
			desc: "incomplete key",
			in: []*Mutation{
				NewInsert(ik, entity),
				NewUpdate(ik, entity),
				NewUpsert(ik, entity),
				NewDelete(ik),
			},
			want: []int{1, 3},
		},
		{
			desc: "bad entity",
			in: []*Mutation{
				NewInsert(k, 1),
				NewUpdate(k, 2),
				NewUpsert(k, 3),
			},
			want: []int{0, 1, 2},
		},
	} {
		_, err := mutationProtos(test.in)
		if err == nil {
			t.Errorf("%s: got nil, want error", test.desc)
			continue
		}
		var got []int
		for i, err := range err.(MultiError) {
			if err != nil {
				got = append(got, i)
			}
		}
		if !testutil.Equal(got, test.want) {
			t.Errorf("%s: got errors at %v, want at %v", test.desc, got, test.want)
		}
	}
}
