// 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"
	"strings"
	"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"
	idiscovery "v.io/x/ref/lib/discovery"
	fdiscovery "v.io/x/ref/lib/discovery/factory"
	"v.io/x/ref/lib/discovery/plugins/mock"
	"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 CreateDatabase(t testing.TB, ctx *context.T, s syncbase.Service, name string) syncbase.Database {
	d := s.Database(ctx, name, nil)
	if err := d.Create(ctx, nil); err != nil {
		Fatalf(t, "d.Create() failed: %v", err)
	}
	return d
}

func CreateCollection(t testing.TB, ctx *context.T, d syncbase.Database, name string) syncbase.Collection {
	c := d.Collection(ctx, 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.Syncgroup(ctx, name)
	sgSpec := wire.SyncgroupSpec{
		Description: description,
		Collections: []wire.Id{c.Id()},
		Perms:       DefaultPerms(wire.AllSyncgroupTags, string(security.AllPrincipals)),
	}
	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(strings.Join([]string{"o", "app", "client"}, security.ChainSeparator), "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()
	df, _ := idiscovery.NewFactory(ctx, mock.New())
	fdiscovery.InjectFactory(df)
	rootp = tsecurity.NewPrincipal("root")
	clientCtx, serverCtx := NewCtx(ctx, rootp, clientSuffix), NewCtx(ctx, rootp, serverSuffix)

	if perms == nil {
		perms = DefaultPerms(access.AllTypicalTags(), "root"+security.ChainSeparator+clientSuffix)
	}
	serverName, stopServer := newServer(serverCtx, perms)
	cleanup = func() {
		stopServer()
		shutdown()
	}
	return
}

func DefaultPerms(tags []access.Tag, patterns ...string) access.Permissions {
	perms := access.Permissions{}
	for _, pattern := range patterns {
		perms.Add(security.BlessingPattern(pattern), access.TagStrings(tags...)...)
	}
	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,
	})
	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)
	}
	service.AddNames(serverCtx, s)
	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
}
