// 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 (
	"fmt"
	"reflect"
	"sort"
	"testing"

	"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/nosql"
	"v.io/v23/syncbase/util"
	"v.io/v23/verror"
	"v.io/x/lib/vlog"
	"v.io/x/ref/test/testutil"
)

// TestCreate tests that object creation works as expected.
func TestCreate(t *testing.T, ctx *context.T, i interface{}) {
	parent := makeLayer(i)
	self := parent.Child("self")
	child := self.Child("child")

	// child.Create should fail since self does not exist.
	if err := child.Create(ctx, nil); verror.ErrorID(err) != verror.ErrNoExist.ID {
		t.Fatalf("child.Create() should have failed: %v", err)
	}

	assertExists(t, ctx, self, "self", false)
	// TODO(ivanpi): Exists on child when parent does not exist currently fails
	// with an error instead of returning false.
	// assertExists(t, ctx, child, "child", false)

	// Create self.
	if err := self.Create(ctx, nil); err != nil {
		t.Fatalf("self.Create() failed: %v", err)
	}
	if gotPerms, wantPerms := getPermsOrDie(t, ctx, self), DefaultPerms("root:client"); !reflect.DeepEqual(gotPerms, wantPerms) {
		t.Errorf("Perms do not match: got %v, want %v", gotPerms, wantPerms)
	}

	assertExists(t, ctx, self, "self", true)
	assertExists(t, ctx, child, "child", false)

	// child.Create should now succeed.
	if err := child.Create(ctx, nil); err != nil {
		t.Fatalf("child.Create() failed: %v", err)
	}

	assertExists(t, ctx, child, "child", true)

	// self.Create should fail since self already exists.
	if err := self.Create(ctx, nil); verror.ErrorID(err) != verror.ErrExist.ID {
		t.Fatalf("self.Create() should have failed: %v", err)
	}

	assertExists(t, ctx, self, "self", true)

	// Test create with non-default perms.
	self2 := parent.Child("self2")
	perms := access.Permissions{}
	perms.Add(security.BlessingPattern("root:client"), string(access.Admin))
	if err := self2.Create(ctx, perms); err != nil {
		t.Fatalf("self2.Create() failed: %v", err)
	}
	if gotPerms, wantPerms := getPermsOrDie(t, ctx, self2), perms; !reflect.DeepEqual(gotPerms, wantPerms) {
		t.Errorf("Perms do not match: got %v, want %v", gotPerms, wantPerms)
	}

	// Even though self2 exists, Exists returns false because Read access is
	// needed.
	assertExists(t, ctx, self2, "self2", false)

	// Test that create fails if the parent perms disallow access.
	perms = DefaultPerms("root:client")
	perms.Blacklist("root:client", string(access.Write))
	if err := parent.SetPermissions(ctx, perms, ""); err != nil {
		t.Fatalf("parent.SetPermissions() failed: %v", err)
	}
	self3 := parent.Child("self3")
	if err := self3.Create(ctx, nil); verror.ErrorID(err) != verror.ErrNoAccess.ID {
		t.Fatalf("self3.Create() should have failed: %v", err)
	}

	assertExists(t, ctx, self, "self", true)
	assertExists(t, ctx, self3, "self3", false)
}

// Tests that Create() checks name validity.
func TestCreateNameValidation(t *testing.T, ctx *context.T, i interface{}, okNames, notOkNames []string) {
	parent := makeLayer(i)
	for _, name := range okNames {
		if err := parent.Child(name).Create(ctx, nil); err != nil {
			t.Fatalf("Create(%q) failed: %v", name, err)
		}
	}
	for _, name := range notOkNames {
		if err := parent.Child(name).Create(ctx, nil); err == nil {
			t.Fatalf("Create(%q) should have failed: %v", name, err)
		} else if name != "" && verror.ErrorID(err) != wire.ErrInvalidName.ID {
			// TODO(sadovsky): Currently for name "" we cannot check for
			// ErrInvalidName, since parent.Child("") dispatches on the parent
			// component. Create will still fail, but for a different reason. If/when
			// we add client-side name validation, we'll be able to check for
			// ErrInvalidName specifically.
			t.Fatalf("Create(%q) should have failed with ErrInvalidName: %v", name, err)
		}
	}
}

// TestDestroy tests that object destruction works as expected.
func TestDestroy(t *testing.T, ctx *context.T, i interface{}) {
	parent := makeLayer(i)
	self := parent.Child("self")
	child := self.Child("child")

	// Create self.
	if err := self.Create(ctx, nil); err != nil {
		t.Fatalf("self.Create() failed: %v", err)
	}

	assertExists(t, ctx, self, "self", true)

	// self.Create should fail, since self already exists.
	if err := self.Create(ctx, nil); verror.ErrorID(err) != verror.ErrExist.ID {
		t.Fatalf("self.Create() should have failed: %v", err)
	}

	assertExists(t, ctx, self, "self", true)

	// By default, self perms are copied from parent, so self.Destroy should
	// succeed.
	if err := self.Destroy(ctx); err != nil {
		t.Fatalf("self.Destroy() failed: %v", err)
	}

	assertExists(t, ctx, self, "self", false)

	// child.Create should fail, since self does not exist.
	if err := child.Create(ctx, nil); verror.ErrorID(err) != verror.ErrNoExist.ID {
		t.Fatalf("child.Create() should have failed: %v", err)
	}

	assertExists(t, ctx, self, "self", false)
	// TODO(ivanpi): Exists on child when parent does not exist currently fails
	// with an error instead of returning false.
	// assertExists(t, ctx, child, "child", false)

	// self.Create should succeed, since self was destroyed.
	if err := self.Create(ctx, nil); err != nil {
		t.Fatalf("self.Create() failed: %v", err)
	}

	assertExists(t, ctx, self, "self", true)
	assertExists(t, ctx, child, "child", false)

	// Test that destroy fails if the perms disallow access.
	self2 := parent.Child("self2")
	if err := self2.Create(ctx, nil); err != nil {
		t.Fatalf("self2.Create() failed: %v", err)
	}
	perms := DefaultPerms("root:client")
	perms.Clear("root:client", string(access.Write), string(access.Admin))
	if err := self2.SetPermissions(ctx, perms, ""); err != nil {
		t.Fatalf("self2.SetPermissions() failed: %v", err)
	}
	if err := self2.Destroy(ctx); verror.ErrorID(err) != verror.ErrNoAccess.ID {
		t.Fatalf("self2.Destroy() should have failed: %v", err)
	}

	assertExists(t, ctx, self2, "self2", true)

	// Create child.
	if err := child.Create(ctx, nil); err != nil {
		t.Fatalf("child.Create() failed: %v", err)
	}

	assertExists(t, ctx, self, "self", true)
	assertExists(t, ctx, child, "child", true)

	// Test that destroy succeeds even if the parent and child perms disallow
	// access.
	perms = DefaultPerms("root:client")
	perms.Clear("root:client", string(access.Write), string(access.Admin))
	if err := parent.SetPermissions(ctx, perms, ""); err != nil {
		t.Fatalf("parent.SetPermissions() failed: %v", err)
	}
	if err := child.SetPermissions(ctx, perms, ""); err != nil {
		t.Fatalf("child.SetPermissions() failed: %v", err)
	}
	if err := self.Destroy(ctx); err != nil {
		t.Fatalf("self.Destroy() failed: %v", err)
	}

	assertExists(t, ctx, self, "self", false)
	// TODO(ivanpi): Reenable when Exists() is fixed to treat nonexistent parent
	// same as nonexistent self.
	//assertExists(t, ctx, child, "child", false)

	// Test that destroy is idempotent.
	if err := self.Destroy(ctx); err != nil {
		t.Fatalf("self.Destroy() failed: %v", err)
	}

	assertExists(t, ctx, self, "self", false)
}

func TestListChildren(t *testing.T, ctx *context.T, i interface{}, names []string) {
	self := makeLayer(i)

	var got, want []string
	var err error

	sortedNames := make([]string, len(names))
	copy(sortedNames, names)
	sort.Strings(sortedNames)
	names = sortedNames

	for i := 0; i <= len(names); i++ {
		got, err = self.ListChildren(ctx)
		want = names[:i]
		if err != nil {
			t.Fatalf("self.ListChildren() failed: %v", err)
		}
		if got == nil {
			got = []string{}
		}
		if !reflect.DeepEqual(got, want) {
			t.Fatalf("Lists do not match: got %v, want %v", got, want)
		}
		if i == len(names) {
			break
		}
		name := names[i]
		if err := self.Child(name).Create(ctx, nil); err != nil {
			t.Fatalf("Create(%q) failed: %v", name, err)
		}
	}
}

// TestPerms tests that {Set,Get}Permissions work as expected.
// TODO(sadovsky): All Vanadium {Set,Get}Permissions tests ought to share this
// test implementation. :)
// Mirrors v.io/groups/x/ref/services/groups/internal/server/server_test.go.
func TestPerms(t *testing.T, ctx *context.T, ac util.AccessController) {
	myperms := access.Permissions{}
	myperms.Add(security.BlessingPattern("root:client"), string(access.Admin))
	// Demonstrate that myperms differs from the current perms.
	if reflect.DeepEqual(myperms, getPermsOrDie(t, ctx, ac)) {
		t.Fatalf("Permissions should not match: %v", myperms)
	}

	var permsBefore, permsAfter access.Permissions
	var versionBefore, versionAfter string

	getPermsAndVersionOrDie := func() (access.Permissions, string) {
		perms, version, err := ac.GetPermissions(ctx)
		if err != nil {
			// Use Fatalf rather than t.Fatalf so we get a stack trace.
			Fatalf(t, "GetPermissions failed: %v", err)
		}
		return perms, version
	}

	// SetPermissions with bad version should fail.
	permsBefore, versionBefore = getPermsAndVersionOrDie()
	if err := ac.SetPermissions(ctx, myperms, "20"); verror.ErrorID(err) != verror.ErrBadVersion.ID {
		t.Fatal("SetPermissions should have failed with version error")
	}
	// Since SetPermissions failed, perms and version should not have changed.
	permsAfter, versionAfter = getPermsAndVersionOrDie()
	if !reflect.DeepEqual(permsAfter, permsBefore) {
		t.Errorf("Perms do not match: got %v, want %v", permsAfter, permsBefore)
	}
	if versionAfter != versionBefore {
		t.Errorf("Versions do not match: got %v, want %v", versionAfter, versionBefore)
	}

	// SetPermissions with correct version should succeed.
	permsBefore, versionBefore = permsAfter, versionAfter
	if err := ac.SetPermissions(ctx, myperms, versionBefore); err != nil {
		t.Fatalf("SetPermissions failed: %v", err)
	}
	// Check that perms and version actually changed.
	permsAfter, versionAfter = getPermsAndVersionOrDie()
	if !reflect.DeepEqual(permsAfter, myperms) {
		t.Errorf("Perms do not match: got %v, want %v", permsAfter, myperms)
	}
	if versionBefore == versionAfter {
		t.Errorf("Versions should not match: %v", versionBefore)
	}

	// SetPermissions with empty version should succeed.
	permsBefore, versionBefore = permsAfter, versionAfter
	myperms.Add(security.BlessingPattern("root:client"), string(access.Read))
	if err := ac.SetPermissions(ctx, myperms, ""); err != nil {
		t.Fatalf("SetPermissions failed: %v", err)
	}
	// Check that perms and version actually changed.
	permsAfter, versionAfter = getPermsAndVersionOrDie()
	if !reflect.DeepEqual(permsAfter, myperms) {
		t.Errorf("Perms do not match: got %v, want %v", permsAfter, myperms)
	}
	if versionBefore == versionAfter {
		t.Errorf("Versions should not match: %v", versionBefore)
	}

	// SetPermissions with unchanged perms should succeed, and version should
	// still change.
	permsBefore, versionBefore = permsAfter, versionAfter
	if err := ac.SetPermissions(ctx, myperms, ""); err != nil {
		t.Fatalf("SetPermissions failed: %v", err)
	}
	// Check that perms did not change and version did change.
	permsAfter, versionAfter = getPermsAndVersionOrDie()
	if !reflect.DeepEqual(permsAfter, permsBefore) {
		t.Errorf("Perms do not match: got %v, want %v", permsAfter, permsBefore)
	}
	if versionBefore == versionAfter {
		t.Errorf("Versions should not match: %v", versionBefore)
	}

	// Take away our access. SetPermissions and GetPermissions should fail.
	if err := ac.SetPermissions(ctx, access.Permissions{}, ""); err != nil {
		t.Fatalf("SetPermissions failed: %v", err)
	}
	if _, _, err := ac.GetPermissions(ctx); verror.ErrorID(err) != verror.ErrNoAccess.ID {
		t.Fatalf("GetPermissions should have failed with access error. Instead got error: %v", err)
	}
	if err := ac.SetPermissions(ctx, myperms, ""); verror.ErrorID(err) != verror.ErrNoAccess.ID {
		t.Fatalf("SetPermissions should have failed with access error. Instead got error: %v", err)
	}
}

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

const notAvailable = "not available"

type layer interface {
	util.AccessController
	Name() string
	FullName() string
	Create(ctx *context.T, perms access.Permissions) error
	Destroy(ctx *context.T) error
	Exists(ctx *context.T) (bool, error)
	ListChildren(ctx *context.T) ([]string, error)
	Child(childName string) layer
}

type service struct {
	syncbase.Service
}

func (s *service) Name() string {
	panic(notAvailable)
}
func (s *service) Create(ctx *context.T, perms access.Permissions) error {
	panic(notAvailable)
}
func (s *service) Destroy(ctx *context.T) error {
	panic(notAvailable)
}
func (s *service) Exists(ctx *context.T) (bool, error) {
	panic(notAvailable)
}
func (s *service) ListChildren(ctx *context.T) ([]string, error) {
	return s.ListApps(ctx)
}
func (s *service) Child(childName string) layer {
	return makeLayer(s.App(childName))
}

type app struct {
	syncbase.App
}

func (a *app) ListChildren(ctx *context.T) ([]string, error) {
	return a.ListDatabases(ctx)
}
func (a *app) Child(childName string) layer {
	return makeLayer(a.NoSQLDatabase(childName, nil))
}

type database struct {
	nosql.Database
}

func (d *database) ListChildren(ctx *context.T) ([]string, error) {
	return d.ListTables(ctx)
}
func (d *database) Child(childName string) layer {
	return makeLayer(d.Table(childName))
}

type table struct {
	nosql.Table
}

func (t *table) SetPermissions(ctx *context.T, perms access.Permissions, version string) error {
	return t.Table.SetPermissions(ctx, perms)
}
func (t *table) GetPermissions(ctx *context.T) (perms access.Permissions, version string, err error) {
	perms, err = t.Table.GetPermissions(ctx)
	return perms, "", err
}
func (t *table) ListChildren(ctx *context.T) ([]string, error) {
	panic(notAvailable)
}
func (t *table) Child(childName string) layer {
	return &row{Row: t.Row(childName), table: t.Table}
}

type row struct {
	nosql.Row
	table nosql.Table
}

func (r *row) Name() string {
	return r.Key()
}
func (r *row) Create(ctx *context.T, perms access.Permissions) error {
	if perms != nil {
		panic(fmt.Sprintf("bad perms: %v", perms))
	}
	return r.Put(ctx, true)
}
func (r *row) Destroy(ctx *context.T) error {
	return r.Delete(ctx)
}
func (r *row) SetPermissions(ctx *context.T, perms access.Permissions, version string) error {
	return r.table.SetPrefixPermissions(ctx, nosql.Prefix(r.Key()), perms)
}
func (r *row) GetPermissions(ctx *context.T) (perms access.Permissions, version string, err error) {
	prefixPerms, err := r.table.GetPrefixPermissions(ctx, r.Key())
	if err != nil {
		return nil, "", err
	}
	return prefixPerms[0].Perms, "", nil
}
func (r *row) ListChildren(ctx *context.T) ([]string, error) {
	panic(notAvailable)
}
func (r *row) Child(childName string) layer {
	panic(notAvailable)
}

func makeLayer(i interface{}) layer {
	switch t := i.(type) {
	case syncbase.Service:
		return &service{t}
	case syncbase.App:
		return &app{t}
	case nosql.Database:
		return &database{t}
	case nosql.Table:
		return &table{t}
	default:
		vlog.Fatalf("unexpected type: %T", t)
	}
	return nil
}

func assertExists(t *testing.T, ctx *context.T, l layer, name string, want bool) {
	if got, err := l.Exists(ctx); err != nil {
		t.Fatal(testutil.FormatLogLine(2, "%s.Exists() failed: %v", name, err))
	} else if got != want {
		t.Error(testutil.FormatLogLine(2, "%s.Exists() got %v, want %v", name, got, want))
	}
}
