// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package testutil

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"reflect"
	"runtime/debug"
	"testing"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/security"
	"v.io/v23/security/access"
	wire "v.io/v23/services/syncbase"
	"v.io/v23/syncbase"
	"v.io/v23/syncbase/util"
	"v.io/v23/vdl"
	"v.io/v23/verror"
	"v.io/v23/vom"
	"v.io/x/lib/vlog"
	"v.io/x/ref/services/syncbase/server"
	"v.io/x/ref/services/syncbase/store"
	"v.io/x/ref/test"
	tsecurity "v.io/x/ref/test/testutil"
)

func Fatal(t testing.TB, args ...interface{}) {
	debug.PrintStack()
	t.Fatal(args...)
}

func Fatalf(t testing.TB, format string, args ...interface{}) {
	debug.PrintStack()
	t.Fatalf(format, args...)
}

// TODO(sadovsky): Standardize on a small set of constants and helper functions
// to share across all Syncbase tests. Currently, our 'featuretests' tests use a
// different set of helpers from our other unit tests.
func DbId(name string) wire.Id {
	return wire.Id{Blessing: "v.io:a:xyz", Name: name}
}

func CreateDatabase(t testing.TB, ctx *context.T, s syncbase.Service, name string) syncbase.Database {
	d := s.DatabaseForId(DbId(name), nil)
	if err := d.Create(ctx, nil); err != nil {
		Fatalf(t, "d.Create() failed: %v", err)
	}
	return d
}

func CxId(name string) wire.Id {
	return wire.Id{Blessing: "v.io:u:sam", Name: name}
}

func CreateCollection(t testing.TB, ctx *context.T, d syncbase.Database, name string) syncbase.Collection {
	c := d.CollectionForId(CxId(name))
	if err := c.Create(ctx, nil); err != nil {
		Fatalf(t, "c.Create() failed: %v", err)
	}
	return c
}

func CreateSyncgroup(
	t testing.TB,
	ctx *context.T,
	d syncbase.Database,
	c syncbase.Collection,
	name, description string,
) syncbase.Syncgroup {
	sg := d.SyncgroupForId(CxId(name))
	sgSpec := wire.SyncgroupSpec{
		Description: description,
		Collections: []wire.Id{c.Id()},
	}
	sgMembership := wire.SyncgroupMemberInfo{}
	if err := sg.Create(ctx, sgSpec, sgMembership); err != nil {
		Fatalf(t, "sg.Create() failed: %v", err)
	}
	return sg
}

// TODO(sadovsky): Drop the 'perms' argument. The only client that passes
// non-nil, syncgroup_test.go, should use SetupOrDieCustom instead.
func SetupOrDie(perms access.Permissions) (clientCtx *context.T, serverName string, cleanup func()) {
	_, clientCtx, serverName, _, cleanup = SetupOrDieCustom("client", "server", perms)
	return
}

// TODO(sadovsky): Switch unit tests to v23test.Shell, then delete this.
func SetupOrDieCustom(clientSuffix, serverSuffix string, perms access.Permissions) (ctx, clientCtx *context.T, serverName string, rootp security.Principal, cleanup func()) {
	ctx, shutdown := test.V23Init()
	rootp = tsecurity.NewPrincipal("root")
	clientCtx, serverCtx := NewCtx(ctx, rootp, clientSuffix), NewCtx(ctx, rootp, serverSuffix)

	if perms == nil {
		perms = DefaultPerms(fmt.Sprintf("%s%s%s", "root", security.ChainSeparator, clientSuffix))
	}
	serverName, stopServer := newServer(serverCtx, perms)
	cleanup = func() {
		stopServer()
		shutdown()
	}
	return
}

func DefaultPerms(patterns ...string) access.Permissions {
	perms := access.Permissions{}
	for _, tag := range access.AllTypicalTags() {
		for _, pattern := range patterns {
			perms.Add(security.BlessingPattern(pattern), string(tag))
		}
	}
	return perms
}

func ScanMatches(ctx *context.T, c syncbase.Collection, r syncbase.RowRange, wantKeys []string, wantValues []interface{}) error {
	if len(wantKeys) != len(wantValues) {
		return fmt.Errorf("bad input args")
	}
	it := c.Scan(ctx, r)
	gotKeys := []string{}
	for it.Advance() {
		gotKey := it.Key()
		gotKeys = append(gotKeys, gotKey)
		i := len(gotKeys) - 1
		if i >= len(wantKeys) {
			continue
		}
		// Check key.
		wantKey := wantKeys[i]
		if gotKey != wantKey {
			return fmt.Errorf("Keys do not match: got %q, want %q", gotKey, wantKey)
		}
		// Check value.
		wantValue := wantValues[i]
		gotValue := reflect.Zero(reflect.TypeOf(wantValue)).Interface()
		if err := it.Value(&gotValue); err != nil {
			return fmt.Errorf("it.Value() failed: %v", err)
		}
		if !reflect.DeepEqual(gotValue, wantValue) {
			return fmt.Errorf("Values do not match: got %v, want %v", gotValue, wantValue)
		}
	}
	if err := it.Err(); err != nil {
		return fmt.Errorf("c.Scan() failed: %v", err)
	}
	if len(gotKeys) != len(wantKeys) {
		return fmt.Errorf("Unmatched keys: got %v, want %v", gotKeys, wantKeys)
	}
	return nil
}

func CheckScan(t testing.TB, ctx *context.T, c syncbase.Collection, r syncbase.RowRange, wantKeys []string, wantValues []interface{}) {
	if err := ScanMatches(ctx, c, r, wantKeys, wantValues); err != nil {
		Fatalf(t, err.Error())
	}
}

func CheckExec(t testing.TB, ctx *context.T, db syncbase.DatabaseHandle, q string, wantHeaders []string, wantResults [][]*vom.RawBytes) {
	gotHeaders, it, err := db.Exec(ctx, q)
	if err != nil {
		t.Errorf("query %q: got %v, want nil", q, err)
	}
	if !reflect.DeepEqual(gotHeaders, wantHeaders) {
		t.Errorf("query %q: got %v, want %v", q, gotHeaders, wantHeaders)
	}
	gotResults := [][]interface{}{}
	for it.Advance() {
		n := it.ResultCount()
		gotResult := make([]interface{}, n)
		for i := 0; i != n; i++ {
			if err := it.Result(i, &gotResult[i]); err != nil {
				t.Errorf("error decoding result: %v", err)
			}
		}
		gotResults = append(gotResults, gotResult)
	}
	if it.Err() != nil {
		t.Errorf("query %q: got %v, want nil", q, it.Err())
	}
	if got, want := vdl.ValueOf(gotResults), vdl.ValueOf(wantResults); !vdl.EqualValue(got, want) {
		t.Errorf("query %q: got %v, want %v", q, got, want)
	}
}

func CheckExecError(t testing.TB, ctx *context.T, db syncbase.DatabaseHandle, q string, wantErrorID verror.ID) {
	_, rs, err := db.Exec(ctx, q)
	if err == nil {
		if rs.Advance() {
			t.Errorf("query %q: got true, want false", q)
		}
		err = rs.Err()
	}
	if verror.ErrorID(err) != wantErrorID {
		t.Errorf("%q", verror.DebugString(err))
		t.Errorf("query %q: got %v, want: %v", q, verror.ErrorID(err), wantErrorID)
	}
}

// A WatchChangeTest is a syncbase.WatchChange that has a public ValueBytes
// field, to allow tests to set it.
type WatchChangeTest struct {
	syncbase.WatchChange
	ValueBytes *vom.RawBytes
}

// WatchChangeEq returns whether *want and *got represent the same value.
func WatchChangeEq(got *syncbase.WatchChange, want *WatchChangeTest) (eq bool) {
	if want.Collection == got.Collection &&
		want.Row == got.Row &&
		want.ChangeType == got.ChangeType &&
		bytes.Equal(want.ResumeMarker, got.ResumeMarker) &&
		want.FromSync == got.FromSync &&
		want.Continued == got.Continued {

		if want.ChangeType == syncbase.DeleteChange {
			eq = true
		} else {
			var wantValue interface{}
			var gotValue interface{}
			gotErr := got.Value(&gotValue)
			wantErr := want.ValueBytes.ToValue(&wantValue)
			eq = ((gotErr == nil) == (wantErr == nil)) &&
				reflect.DeepEqual(gotValue, wantValue)
		}
	}
	return eq
}

// CheckWatch checks that the sequence of elements from the watch stream starts
// with the given slice of watch changes.
func CheckWatch(t testing.TB, wstream syncbase.WatchStream, changes []WatchChangeTest) {
	for _, want := range changes {
		if !wstream.Advance() {
			Fatalf(t, "wstream.Advance() reached the end: %v", wstream.Err())
		}
		if got := wstream.Change(); !WatchChangeEq(&got, &want) {
			Fatalf(t, "unexpected watch change: got %v, want %v", got, want)
		}
	}
}

func DefaultSchema(version int32) *syncbase.Schema {
	return &syncbase.Schema{
		Metadata: wire.SchemaMetadata{
			Version: version,
		},
	}
}

////////////////////////////////////////
// Internal helpers

func getPermsOrDie(t testing.TB, ctx *context.T, ac util.AccessController) access.Permissions {
	perms, _, err := ac.GetPermissions(ctx)
	if err != nil {
		Fatalf(t, "GetPermissions failed: %v", err)
	}
	return perms
}

func newServer(serverCtx *context.T, perms access.Permissions) (string, func()) {
	if perms == nil {
		vlog.Fatal("perms must be specified")
	}
	rootDir, err := ioutil.TempDir("", "syncbase")
	if err != nil {
		vlog.Fatal("ioutil.TempDir() failed: ", err)
	}
	serverCtx, cancel := context.WithCancel(serverCtx)
	service, err := server.NewService(serverCtx, server.ServiceOptions{
		Perms:           perms,
		RootDir:         rootDir,
		Engine:          store.EngineForTest,
		DevMode:         true,
		SkipPublishInNh: true,
	})
	if err != nil {
		vlog.Fatal("server.NewService() failed: ", err)
	}
	serverCtx, s, err := v23.WithNewDispatchingServer(serverCtx, "", server.NewDispatcher(service))
	if err != nil {
		vlog.Fatal("v23.WithNewDispatchingServer() failed: ", err)
	}
	name := s.Status().Endpoints[0].Name()
	return name, func() {
		cancel()
		<-s.Closed()
		service.Close()
		os.RemoveAll(rootDir)
	}
}

// Creates a new context object with blessing "root:<suffix>", configured to
// present this blessing when acting as a server as well as when acting as a
// client and talking to a server that presents a blessing rooted at "root".
// TODO(sadovsky): Switch unit tests to v23test.Shell, then delete this.
func NewCtx(ctx *context.T, rootp security.Principal, suffix string) *context.T {
	// Principal for the new context.
	p := tsecurity.NewPrincipal(suffix)
	rootb, _ := rootp.BlessingStore().Default()

	// Bless the new principal as "root:<suffix>".
	blessings, err := rootp.Bless(p.PublicKey(), rootb, suffix, security.UnconstrainedUse())
	if err != nil {
		vlog.Fatal("rootp.Bless() failed: ", err)
	}

	// Make it so users of the new context present their "root:<suffix>" blessing
	// when talking to servers with blessings rooted at "root".
	if _, err := p.BlessingStore().Set(blessings, security.BlessingPattern("root")); err != nil {
		vlog.Fatal("p.BlessingStore().Set() failed: ", err)
	}

	// Make it so that when users of the new context act as a server, they present
	// their "root:<suffix>" blessing.
	if err := p.BlessingStore().SetDefault(blessings); err != nil {
		vlog.Fatal("p.BlessingStore().SetDefault() failed: ", err)
	}

	// Have users of the prepared context treat root's public key as an authority
	// on all blessings rooted at "root".
	if err := security.AddToRoots(p, blessings); err != nil {
		vlog.Fatal("AddToRoots() failed: ", err)
	}

	resCtx, err := v23.WithPrincipal(ctx, p)
	if err != nil {
		vlog.Fatal("v23.WithPrincipal() failed: ", err)
	}

	return resCtx
}
