// Copyright 2011 Google Inc. All Rights Reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package datastore

import (
	"errors"
	"fmt"
	"reflect"
	"strings"
	"testing"

	"github.com/golang/protobuf/proto"

	"google.golang.org/appengine/internal"
	"google.golang.org/appengine/internal/aetesting"
	pb "google.golang.org/appengine/internal/datastore"
)

var (
	path1 = &pb.Path{
		Element: []*pb.Path_Element{
			{
				Type: proto.String("Gopher"),
				Id:   proto.Int64(6),
			},
		},
	}
	path2 = &pb.Path{
		Element: []*pb.Path_Element{
			{
				Type: proto.String("Gopher"),
				Id:   proto.Int64(6),
			},
			{
				Type: proto.String("Gopher"),
				Id:   proto.Int64(8),
			},
		},
	}
)

func fakeRunQuery(in *pb.Query, out *pb.QueryResult) error {
	expectedIn := &pb.Query{
		App:     proto.String("dev~fake-app"),
		Kind:    proto.String("Gopher"),
		Compile: proto.Bool(true),
	}
	if !proto.Equal(in, expectedIn) {
		return fmt.Errorf("unsupported argument: got %v want %v", in, expectedIn)
	}
	*out = pb.QueryResult{
		Result: []*pb.EntityProto{
			{
				Key: &pb.Reference{
					App:  proto.String("s~test-app"),
					Path: path1,
				},
				EntityGroup: path1,
				Property: []*pb.Property{
					{
						Meaning: pb.Property_TEXT.Enum(),
						Name:    proto.String("Name"),
						Value: &pb.PropertyValue{
							StringValue: proto.String("George"),
						},
					},
					{
						Name: proto.String("Height"),
						Value: &pb.PropertyValue{
							Int64Value: proto.Int64(32),
						},
					},
				},
			},
			{
				Key: &pb.Reference{
					App:  proto.String("s~test-app"),
					Path: path2,
				},
				EntityGroup: path1, // ancestor is George
				Property: []*pb.Property{
					{
						Meaning: pb.Property_TEXT.Enum(),
						Name:    proto.String("Name"),
						Value: &pb.PropertyValue{
							StringValue: proto.String("Rufus"),
						},
					},
					// No height for Rufus.
				},
			},
		},
		MoreResults: proto.Bool(false),
	}
	return nil
}

type StructThatImplementsPLS struct{}

func (StructThatImplementsPLS) Load(p []Property) error   { return nil }
func (StructThatImplementsPLS) Save() ([]Property, error) { return nil, nil }

var _ PropertyLoadSaver = StructThatImplementsPLS{}

type StructPtrThatImplementsPLS struct{}

func (*StructPtrThatImplementsPLS) Load(p []Property) error   { return nil }
func (*StructPtrThatImplementsPLS) Save() ([]Property, error) { return nil, nil }

var _ PropertyLoadSaver = &StructPtrThatImplementsPLS{}

type PropertyMap map[string]Property

func (m PropertyMap) Load(props []Property) error {
	for _, p := range props {
		if p.Multiple {
			return errors.New("PropertyMap does not support multiple properties")
		}
		m[p.Name] = p
	}
	return nil
}

func (m PropertyMap) Save() ([]Property, error) {
	props := make([]Property, 0, len(m))
	for _, p := range m {
		if p.Multiple {
			return nil, errors.New("PropertyMap does not support multiple properties")
		}
		props = append(props, p)
	}
	return props, nil
}

var _ PropertyLoadSaver = PropertyMap{}

type Gopher struct {
	Name   string
	Height int
}

// typeOfEmptyInterface is the type of interface{}, but we can't use
// reflect.TypeOf((interface{})(nil)) directly because TypeOf takes an
// interface{}.
var typeOfEmptyInterface = reflect.TypeOf((*interface{})(nil)).Elem()

func TestCheckMultiArg(t *testing.T) {
	testCases := []struct {
		v        interface{}
		mat      multiArgType
		elemType reflect.Type
	}{
		// Invalid cases.
		{nil, multiArgTypeInvalid, nil},
		{Gopher{}, multiArgTypeInvalid, nil},
		{&Gopher{}, multiArgTypeInvalid, nil},
		{PropertyList{}, multiArgTypeInvalid, nil}, // This is a special case.
		{PropertyMap{}, multiArgTypeInvalid, nil},
		{[]*PropertyList(nil), multiArgTypeInvalid, nil},
		{[]*PropertyMap(nil), multiArgTypeInvalid, nil},
		{[]**Gopher(nil), multiArgTypeInvalid, nil},
		{[]*interface{}(nil), multiArgTypeInvalid, nil},
		// Valid cases.
		{
			[]PropertyList(nil),
			multiArgTypePropertyLoadSaver,
			reflect.TypeOf(PropertyList{}),
		},
		{
			[]PropertyMap(nil),
			multiArgTypePropertyLoadSaver,
			reflect.TypeOf(PropertyMap{}),
		},
		{
			[]StructThatImplementsPLS(nil),
			multiArgTypePropertyLoadSaver,
			reflect.TypeOf(StructThatImplementsPLS{}),
		},
		{
			[]StructPtrThatImplementsPLS(nil),
			multiArgTypePropertyLoadSaver,
			reflect.TypeOf(StructPtrThatImplementsPLS{}),
		},
		{
			[]Gopher(nil),
			multiArgTypeStruct,
			reflect.TypeOf(Gopher{}),
		},
		{
			[]*Gopher(nil),
			multiArgTypeStructPtr,
			reflect.TypeOf(Gopher{}),
		},
		{
			[]interface{}(nil),
			multiArgTypeInterface,
			typeOfEmptyInterface,
		},
	}
	for _, tc := range testCases {
		mat, elemType := checkMultiArg(reflect.ValueOf(tc.v))
		if mat != tc.mat || elemType != tc.elemType {
			t.Errorf("checkMultiArg(%T): got %v, %v want %v, %v",
				tc.v, mat, elemType, tc.mat, tc.elemType)
		}
	}
}

func TestSimpleQuery(t *testing.T) {
	struct1 := Gopher{Name: "George", Height: 32}
	struct2 := Gopher{Name: "Rufus"}
	pList1 := PropertyList{
		{
			Name:  "Name",
			Value: "George",
		},
		{
			Name:  "Height",
			Value: int64(32),
		},
	}
	pList2 := PropertyList{
		{
			Name:  "Name",
			Value: "Rufus",
		},
	}
	pMap1 := PropertyMap{
		"Name": Property{
			Name:  "Name",
			Value: "George",
		},
		"Height": Property{
			Name:  "Height",
			Value: int64(32),
		},
	}
	pMap2 := PropertyMap{
		"Name": Property{
			Name:  "Name",
			Value: "Rufus",
		},
	}

	testCases := []struct {
		dst  interface{}
		want interface{}
	}{
		// The destination must have type *[]P, *[]S or *[]*S, for some non-interface
		// type P such that *P implements PropertyLoadSaver, or for some struct type S.
		{new([]Gopher), &[]Gopher{struct1, struct2}},
		{new([]*Gopher), &[]*Gopher{&struct1, &struct2}},
		{new([]PropertyList), &[]PropertyList{pList1, pList2}},
		{new([]PropertyMap), &[]PropertyMap{pMap1, pMap2}},

		// Any other destination type is invalid.
		{0, nil},
		{Gopher{}, nil},
		{PropertyList{}, nil},
		{PropertyMap{}, nil},
		{[]int{}, nil},
		{[]Gopher{}, nil},
		{[]PropertyList{}, nil},
		{new(int), nil},
		{new(Gopher), nil},
		{new(PropertyList), nil}, // This is a special case.
		{new(PropertyMap), nil},
		{new([]int), nil},
		{new([]map[int]int), nil},
		{new([]map[string]Property), nil},
		{new([]map[string]interface{}), nil},
		{new([]*int), nil},
		{new([]*map[int]int), nil},
		{new([]*map[string]Property), nil},
		{new([]*map[string]interface{}), nil},
		{new([]**Gopher), nil},
		{new([]*PropertyList), nil},
		{new([]*PropertyMap), nil},
	}
	for _, tc := range testCases {
		nCall := 0
		c := aetesting.FakeSingleContext(t, "datastore_v3", "RunQuery", func(in *pb.Query, out *pb.QueryResult) error {
			nCall++
			return fakeRunQuery(in, out)
		})
		c = internal.WithAppIDOverride(c, "dev~fake-app")

		var (
			expectedErr   error
			expectedNCall int
		)
		if tc.want == nil {
			expectedErr = ErrInvalidEntityType
		} else {
			expectedNCall = 1
		}
		keys, err := NewQuery("Gopher").GetAll(c, tc.dst)
		if err != expectedErr {
			t.Errorf("dst type %T: got error [%v], want [%v]", tc.dst, err, expectedErr)
			continue
		}
		if nCall != expectedNCall {
			t.Errorf("dst type %T: Context.Call was called an incorrect number of times: got %d want %d", tc.dst, nCall, expectedNCall)
			continue
		}
		if err != nil {
			continue
		}

		key1 := NewKey(c, "Gopher", "", 6, nil)
		expectedKeys := []*Key{
			key1,
			NewKey(c, "Gopher", "", 8, key1),
		}
		if l1, l2 := len(keys), len(expectedKeys); l1 != l2 {
			t.Errorf("dst type %T: got %d keys, want %d keys", tc.dst, l1, l2)
			continue
		}
		for i, key := range keys {
			if key.AppID() != "s~test-app" {
				t.Errorf(`dst type %T: Key #%d's AppID = %q, want "s~test-app"`, tc.dst, i, key.AppID())
				continue
			}
			if !keysEqual(key, expectedKeys[i]) {
				t.Errorf("dst type %T: got key #%d %v, want %v", tc.dst, i, key, expectedKeys[i])
				continue
			}
		}

		if !reflect.DeepEqual(tc.dst, tc.want) {
			t.Errorf("dst type %T: Entities got %+v, want %+v", tc.dst, tc.dst, tc.want)
			continue
		}
	}
}

// keysEqual is like (*Key).Equal, but ignores the App ID.
func keysEqual(a, b *Key) bool {
	for a != nil && b != nil {
		if a.Kind() != b.Kind() || a.StringID() != b.StringID() || a.IntID() != b.IntID() {
			return false
		}
		a, b = a.Parent(), b.Parent()
	}
	return a == b
}

func TestQueriesAreImmutable(t *testing.T) {
	// Test that deriving q2 from q1 does not modify q1.
	q0 := NewQuery("foo")
	q1 := NewQuery("foo")
	q2 := q1.Offset(2)
	if !reflect.DeepEqual(q0, q1) {
		t.Errorf("q0 and q1 were not equal")
	}
	if reflect.DeepEqual(q1, q2) {
		t.Errorf("q1 and q2 were equal")
	}

	// Test that deriving from q4 twice does not conflict, even though
	// q4 has a long list of order clauses. This tests that the arrays
	// backed by a query's slice of orders are not shared.
	f := func() *Query {
		q := NewQuery("bar")
		// 47 is an ugly number that is unlikely to be near a re-allocation
		// point in repeated append calls. For example, it's not near a power
		// of 2 or a multiple of 10.
		for i := 0; i < 47; i++ {
			q = q.Order(fmt.Sprintf("x%d", i))
		}
		return q
	}
	q3 := f().Order("y")
	q4 := f()
	q5 := q4.Order("y")
	q6 := q4.Order("z")
	if !reflect.DeepEqual(q3, q5) {
		t.Errorf("q3 and q5 were not equal")
	}
	if reflect.DeepEqual(q5, q6) {
		t.Errorf("q5 and q6 were equal")
	}
}

func TestFilterParser(t *testing.T) {
	testCases := []struct {
		filterStr     string
		wantOK        bool
		wantFieldName string
		wantOp        operator
	}{
		// Supported ops.
		{"x<", true, "x", lessThan},
		{"x <", true, "x", lessThan},
		{"x  <", true, "x", lessThan},
		{"   x   <  ", true, "x", lessThan},
		{"x <=", true, "x", lessEq},
		{"x =", true, "x", equal},
		{"x >=", true, "x", greaterEq},
		{"x >", true, "x", greaterThan},
		{"in >", true, "in", greaterThan},
		{"in>", true, "in", greaterThan},
		// Valid but (currently) unsupported ops.
		{"x!=", false, "", 0},
		{"x !=", false, "", 0},
		{" x  !=  ", false, "", 0},
		{"x IN", false, "", 0},
		{"x in", false, "", 0},
		// Invalid ops.
		{"x EQ", false, "", 0},
		{"x lt", false, "", 0},
		{"x <>", false, "", 0},
		{"x >>", false, "", 0},
		{"x ==", false, "", 0},
		{"x =<", false, "", 0},
		{"x =>", false, "", 0},
		{"x !", false, "", 0},
		{"x ", false, "", 0},
		{"x", false, "", 0},
	}
	for _, tc := range testCases {
		q := NewQuery("foo").Filter(tc.filterStr, 42)
		if ok := q.err == nil; ok != tc.wantOK {
			t.Errorf("%q: ok=%t, want %t", tc.filterStr, ok, tc.wantOK)
			continue
		}
		if !tc.wantOK {
			continue
		}
		if len(q.filter) != 1 {
			t.Errorf("%q: len=%d, want %d", tc.filterStr, len(q.filter), 1)
			continue
		}
		got, want := q.filter[0], filter{tc.wantFieldName, tc.wantOp, 42}
		if got != want {
			t.Errorf("%q: got %v, want %v", tc.filterStr, got, want)
			continue
		}
	}
}

func TestQueryToProto(t *testing.T) {
	// The context is required to make Keys for the test cases.
	var got *pb.Query
	NoErr := errors.New("No error")
	c := aetesting.FakeSingleContext(t, "datastore_v3", "RunQuery", func(in *pb.Query, out *pb.QueryResult) error {
		got = in
		return NoErr // return a non-nil error so Run doesn't keep going.
	})
	c = internal.WithAppIDOverride(c, "dev~fake-app")

	testCases := []struct {
		desc  string
		query *Query
		want  *pb.Query
		err   string
	}{
		{
			desc:  "empty",
			query: NewQuery(""),
			want:  &pb.Query{},
		},
		{
			desc:  "standard query",
			query: NewQuery("kind").Order("-I").Filter("I >", 17).Filter("U =", "Dave").Limit(7).Offset(42).BatchSize(5),
			want: &pb.Query{
				Kind: proto.String("kind"),
				Filter: []*pb.Query_Filter{
					{
						Op: pb.Query_Filter_GREATER_THAN.Enum(),
						Property: []*pb.Property{
							{
								Name:     proto.String("I"),
								Value:    &pb.PropertyValue{Int64Value: proto.Int64(17)},
								Multiple: proto.Bool(false),
							},
						},
					},
					{
						Op: pb.Query_Filter_EQUAL.Enum(),
						Property: []*pb.Property{
							{
								Name:     proto.String("U"),
								Value:    &pb.PropertyValue{StringValue: proto.String("Dave")},
								Multiple: proto.Bool(false),
							},
						},
					},
				},
				Order: []*pb.Query_Order{
					{
						Property:  proto.String("I"),
						Direction: pb.Query_Order_DESCENDING.Enum(),
					},
				},
				Limit:  proto.Int32(7),
				Offset: proto.Int32(42),
				Count:  proto.Int32(5),
			},
		},
		{
			desc:  "ancestor",
			query: NewQuery("").Ancestor(NewKey(c, "kind", "Mummy", 0, nil)),
			want: &pb.Query{
				Ancestor: &pb.Reference{
					App: proto.String("dev~fake-app"),
					Path: &pb.Path{
						Element: []*pb.Path_Element{{Type: proto.String("kind"), Name: proto.String("Mummy")}},
					},
				},
			},
		},
		{
			desc:  "projection",
			query: NewQuery("").Project("A", "B"),
			want: &pb.Query{
				PropertyName: []string{"A", "B"},
			},
		},
		{
			desc:  "projection with distinct",
			query: NewQuery("").Project("A", "B").Distinct(),
			want: &pb.Query{
				PropertyName:        []string{"A", "B"},
				GroupByPropertyName: []string{"A", "B"},
			},
		},
		{
			desc:  "distinct on",
			query: NewQuery("").Project("A", "B").DistinctOn("A"),
			want: &pb.Query{
				PropertyName:        []string{"A", "B"},
				GroupByPropertyName: []string{"A"},
			},
		},
		{
			desc:  "keys only",
			query: NewQuery("").KeysOnly(),
			want: &pb.Query{
				KeysOnly:           proto.Bool(true),
				RequirePerfectPlan: proto.Bool(true),
			},
		},
		{
			desc:  "empty filter",
			query: NewQuery("kind").Filter("=", 17),
			err:   "empty query filter field nam",
		},
		{
			desc:  "bad filter type",
			query: NewQuery("kind").Filter("M =", map[string]bool{}),
			err:   "bad query filter value type",
		},
		{
			desc:  "bad filter operator",
			query: NewQuery("kind").Filter("I <<=", 17),
			err:   `invalid operator "<<=" in filter "I <<="`,
		},
		{
			desc:  "empty order",
			query: NewQuery("kind").Order(""),
			err:   "empty order",
		},
		{
			desc:  "bad order direction",
			query: NewQuery("kind").Order("+I"),
			err:   `invalid order: "+I`,
		},
	}

	for _, tt := range testCases {
		got = nil
		if _, err := tt.query.Run(c).Next(nil); err != NoErr {
			if tt.err == "" || !strings.Contains(err.Error(), tt.err) {
				t.Errorf("%s: error %v, want %q", tt.desc, err, tt.err)
			}
			continue
		}
		if tt.err != "" {
			t.Errorf("%s: no error, want %q", tt.desc, tt.err)
			continue
		}
		// Fields that are common to all protos.
		tt.want.App = proto.String("dev~fake-app")
		tt.want.Compile = proto.Bool(true)
		if !proto.Equal(got, tt.want) {
			t.Errorf("%s:\ngot  %v\nwant %v", tt.desc, got, tt.want)
		}
	}
}
