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

// A runner for the cross-language tests.

package firestore

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"math"
	"path"
	"path/filepath"
	"strings"
	"testing"

	pb "cloud.google.com/go/firestore/genproto"
	"github.com/golang/protobuf/proto"
	"github.com/golang/protobuf/ptypes"
	ts "github.com/golang/protobuf/ptypes/timestamp"
	"golang.org/x/net/context"
	fspb "google.golang.org/genproto/googleapis/firestore/v1beta1"
)

func TestCrossLanguageTests(t *testing.T) {
	const dir = "testdata"
	fis, err := ioutil.ReadDir(dir)
	if err != nil {
		t.Fatal(err)
	}
	n := 0
	for _, fi := range fis {
		if strings.HasSuffix(fi.Name(), ".textproto") {
			runTestFromFile(t, filepath.Join(dir, fi.Name()))
			n++
		}
	}
	t.Logf("ran %d cross-language tests", n)
}

func runTestFromFile(t *testing.T, filename string) {
	bytes, err := ioutil.ReadFile(filename)
	if err != nil {
		t.Fatalf("%s: %v", filename, err)
	}
	var test pb.Test
	if err := proto.UnmarshalText(string(bytes), &test); err != nil {
		t.Fatalf("unmarshalling %s: %v", filename, err)
	}
	msg := fmt.Sprintf("%s (file %s)", test.Description, filepath.Base(filename))
	runTest(t, msg, &test)
}

func runTest(t *testing.T, msg string, test *pb.Test) {
	check := func(gotErr error, wantErr bool) bool {
		if wantErr && gotErr == nil {
			t.Errorf("%s: got nil, want error", msg)
			return false
		} else if !wantErr && gotErr != nil {
			t.Errorf("%s: %v", msg, gotErr)
			return false
		}
		return true
	}

	ctx := context.Background()
	c, srv := newMock(t)
	switch tt := test.Test.(type) {
	case *pb.Test_Get:
		req := &fspb.BatchGetDocumentsRequest{
			Database:  c.path(),
			Documents: []string{tt.Get.DocRefPath},
		}
		srv.addRPC(req, []interface{}{
			&fspb.BatchGetDocumentsResponse{
				Result: &fspb.BatchGetDocumentsResponse_Found{&fspb.Document{
					Name:       tt.Get.DocRefPath,
					CreateTime: &ts.Timestamp{},
					UpdateTime: &ts.Timestamp{},
				}},
				ReadTime: &ts.Timestamp{},
			},
		})
		ref := docRefFromPath(tt.Get.DocRefPath, c)
		_, err := ref.Get(ctx)
		if err != nil {
			t.Errorf("%s: %v", msg, err)
			return
		}
		// Checking response would just be testing the function converting a Document
		// proto to a DocumentSnapshot, hence uninteresting.

	case *pb.Test_Create:
		srv.addRPC(tt.Create.Request, commitResponseForSet)
		ref := docRefFromPath(tt.Create.DocRefPath, c)
		data, err := convertData(tt.Create.JsonData)
		if err != nil {
			t.Errorf("%s: %v", msg, err)
			return
		}
		_, err = ref.Create(ctx, data)
		check(err, tt.Create.IsError)

	case *pb.Test_Set:
		srv.addRPC(tt.Set.Request, commitResponseForSet)
		ref := docRefFromPath(tt.Set.DocRefPath, c)
		data, err := convertData(tt.Set.JsonData)
		if err != nil {
			t.Errorf("%s: %v", msg, err)
			return
		}
		var opts []SetOption
		if tt.Set.Option != nil {
			opts = []SetOption{convertSetOption(tt.Set.Option)}
		}
		_, err = ref.Set(ctx, data, opts...)
		check(err, tt.Set.IsError)

	case *pb.Test_Update:
		// Ignore Update test because we only support UpdatePaths.
		// Not to worry, every Update test has a corresponding UpdatePaths test.

	case *pb.Test_UpdatePaths:
		srv.addRPC(tt.UpdatePaths.Request, commitResponseForSet)
		ref := docRefFromPath(tt.UpdatePaths.DocRefPath, c)
		preconds := convertPrecondition(t, tt.UpdatePaths.Precondition)
		paths := convertFieldPaths(tt.UpdatePaths.FieldPaths)
		var ups []Update
		for i, path := range paths {
			val, err := convertJSONValue(tt.UpdatePaths.JsonValues[i])
			if err != nil {
				t.Fatalf("%s: %v", msg, err)
			}
			ups = append(ups, Update{
				FieldPath: path,
				Value:     val,
			})
		}
		_, err := ref.Update(ctx, ups, preconds...)
		check(err, tt.UpdatePaths.IsError)

	case *pb.Test_Delete:
		srv.addRPC(tt.Delete.Request, commitResponseForSet)
		ref := docRefFromPath(tt.Delete.DocRefPath, c)
		preconds := convertPrecondition(t, tt.Delete.Precondition)
		_, err := ref.Delete(ctx, preconds...)
		check(err, tt.Delete.IsError)

	case *pb.Test_Query:
		q := convertQuery(t, tt.Query)
		got, err := q.toProto()
		if check(err, tt.Query.IsError) && err == nil {
			if want := tt.Query.Query; !proto.Equal(got, want) {
				t.Errorf("%s\ngot:  %s\nwant: %s", msg, proto.MarshalTextString(got), proto.MarshalTextString(want))
			}
		}

	default:
		t.Fatalf("unknown test type %T", tt)
	}
}

func docRefFromPath(p string, c *Client) *DocumentRef {
	return &DocumentRef{
		Path:   p,
		ID:     path.Base(p),
		Parent: &CollectionRef{c: c},
	}
}

func convertJSONValue(jv string) (interface{}, error) {
	var val interface{}
	if err := json.Unmarshal([]byte(jv), &val); err != nil {
		return nil, err
	}
	return convertTestValue(val), nil
}

func convertData(jsonData string) (map[string]interface{}, error) {
	var m map[string]interface{}
	if err := json.Unmarshal([]byte(jsonData), &m); err != nil {
		return nil, err
	}
	return convertTestMap(m), nil
}

func convertTestMap(m map[string]interface{}) map[string]interface{} {
	for k, v := range m {
		m[k] = convertTestValue(v)
	}
	return m
}

func convertTestValue(v interface{}) interface{} {
	switch v := v.(type) {
	case string:
		switch v {
		case "ServerTimestamp":
			return ServerTimestamp
		case "Delete":
			return Delete
		case "NaN":
			return math.NaN()
		default:
			return v
		}
	case float64:
		if v == float64(int(v)) {
			return int(v)
		}
		return v
	case []interface{}:
		for i, e := range v {
			v[i] = convertTestValue(e)
		}
		return v
	case map[string]interface{}:
		return convertTestMap(v)
	default:
		return v
	}
}

func convertSetOption(opt *pb.SetOption) SetOption {
	if opt.All {
		return MergeAll
	}
	return Merge(convertFieldPaths(opt.Fields)...)
}

func convertFieldPaths(fps []*pb.FieldPath) []FieldPath {
	var res []FieldPath
	for _, fp := range fps {
		res = append(res, fp.Field)
	}
	return res
}

func convertPrecondition(t *testing.T, fp *fspb.Precondition) []Precondition {
	if fp == nil {
		return nil
	}
	var pc Precondition
	switch fp := fp.ConditionType.(type) {
	case *fspb.Precondition_Exists:
		pc = exists(fp.Exists)
	case *fspb.Precondition_UpdateTime:
		tm, err := ptypes.Timestamp(fp.UpdateTime)
		if err != nil {
			t.Fatal(err)
		}
		pc = LastUpdateTime(tm)
	default:
		t.Fatalf("unknown precondition type %T", fp)
	}
	return []Precondition{pc}
}

func convertQuery(t *testing.T, qt *pb.QueryTest) Query {
	parts := strings.Split(qt.CollPath, "/")
	q := Query{
		parentPath:   strings.Join(parts[:len(parts)-2], "/"),
		collectionID: parts[len(parts)-1],
	}
	for _, c := range qt.Clauses {
		switch c := c.Clause.(type) {
		case *pb.Clause_Select:
			q = q.SelectPaths(convertFieldPaths(c.Select.Fields)...)
		case *pb.Clause_OrderBy:
			var dir Direction
			switch c.OrderBy.Direction {
			case "asc":
				dir = Asc
			case "desc":
				dir = Desc
			default:
				t.Fatalf("bad direction: %q", c.OrderBy.Direction)
			}
			q = q.OrderByPath(FieldPath(c.OrderBy.Path.Field), dir)
		case *pb.Clause_Where:
			val, err := convertJSONValue(c.Where.JsonValue)
			if err != nil {
				t.Fatal(err)
			}
			q = q.WherePath(FieldPath(c.Where.Path.Field), c.Where.Op, val)
		case *pb.Clause_Offset:
			q = q.Offset(int(c.Offset))
		case *pb.Clause_Limit:
			q = q.Limit(int(c.Limit))
		case *pb.Clause_StartAt:
			q = q.StartAt(convertCursor(t, c.StartAt)...)
		case *pb.Clause_StartAfter:
			q = q.StartAfter(convertCursor(t, c.StartAfter)...)
		case *pb.Clause_EndAt:
			q = q.EndAt(convertCursor(t, c.EndAt)...)
		case *pb.Clause_EndBefore:
			q = q.EndBefore(convertCursor(t, c.EndBefore)...)
		default:
			t.Fatalf("bad clause type %T", c)
		}
	}
	return q
}

// Returns args to a cursor method (StartAt, etc.).
func convertCursor(t *testing.T, c *pb.Cursor) []interface{} {
	if c.DocSnapshot != nil {
		ds, err := convertDocSnapshot(c.DocSnapshot)
		if err != nil {
			t.Fatal(err)
		}
		return []interface{}{ds}
	}
	var vals []interface{}
	for _, jv := range c.JsonValues {
		v, err := convertJSONValue(jv)
		if err != nil {
			t.Fatal(err)
		}
		vals = append(vals, v)
	}
	return vals
}

func convertDocSnapshot(ds *pb.DocSnapshot) (*DocumentSnapshot, error) {
	data, err := convertData(ds.JsonData)
	if err != nil {
		return nil, err
	}
	doc, transformPaths, err := toProtoDocument(data)
	if err != nil {
		return nil, err
	}
	if len(transformPaths) > 0 {
		return nil, errors.New("saw transform paths in DocSnapshot")
	}
	return &DocumentSnapshot{
		Ref: &DocumentRef{
			Path:   ds.Path,
			Parent: &CollectionRef{Path: path.Dir(ds.Path)},
		},
		proto: doc,
	}, nil
}
