// Copyright 2016 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 checker_test

import (
	"io/ioutil"
	"os"
	"testing"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/rpc"
	"v.io/v23/security"
	"v.io/v23/syncbase"
	_ "v.io/x/ref/runtime/factories/roaming"
	"v.io/x/ref/services/syncbase/longevity_tests/checker"
	"v.io/x/ref/services/syncbase/longevity_tests/model"
	"v.io/x/ref/services/syncbase/longevity_tests/util"
	"v.io/x/ref/services/syncbase/server"
	"v.io/x/ref/services/syncbase/store"
	"v.io/x/ref/services/syncbase/testutil"
)

func newServer(t *testing.T, ctx *context.T) (string, func()) {
	rootDir, err := ioutil.TempDir("", "syncbase")
	if err != nil {
		t.Fatalf("ioutil.TempDir() failed: %v", err)
	}
	perms := testutil.DefaultPerms("...")
	serverCtx, cancel := context.WithCancel(ctx)
	service, err := server.NewService(serverCtx, server.ServiceOptions{
		Perms:           perms,
		RootDir:         rootDir,
		Engine:          store.EngineForTest,
		DevMode:         true,
		SkipPublishInNh: true,
	})
	if err != nil {
		t.Fatalf("server.NewService() failed: %v", err)
	}
	serverCtx, s, err := v23.WithNewDispatchingServer(serverCtx, "", server.NewDispatcher(service))
	if err != nil {
		t.Fatalf("v23.WithNewDispatchingServer() failed: %v", err)
	}
	name := s.Status().Endpoints[0].Name()
	return name, func() {
		cancel()
		<-s.Closed()
		service.Close()
		os.RemoveAll(rootDir)
	}
}

// setupServers runs n syncbase servers and returns a slice of services, a
// model universe containing the servers, and a cancel func.
func setupServers(t *testing.T, n int) (*context.T, []syncbase.Service, model.Universe, func()) {
	ctx, cancel := v23.Init()
	ctx = v23.WithListenSpec(ctx, rpc.ListenSpec{
		Addrs: rpc.ListenAddrs{{"tcp", "127.0.0.1:0"}},
	})

	services := []syncbase.Service{}
	cancelFuncs := []func(){}

	universe := model.Universe{
		Users: model.UserSet{},
	}

	for i := 0; i < n; i++ {
		serverName, cancel := newServer(t, ctx)
		services = append(services, syncbase.NewService(serverName))
		cancelFuncs = append(cancelFuncs, cancel)

		universe.Users = append(universe.Users,
			&model.User{
				Devices: model.DeviceSet{
					&model.Device{Name: serverName},
				},
			},
		)
	}

	return ctx, services, universe, func() {
		for _, cancelFunc := range cancelFuncs {
			cancelFunc()
		}
		cancel()
	}
}

// TestEqualityEqualServices checks that Equality returns no errors if the
// syncbases have identical databases, collections, and rows.
func TestEqualityEqualServices(t *testing.T) {
	// Start three syncbase servers.
	ctx, services, universe, cancel := setupServers(t, 3)
	defer cancel()

	blessing, _ := v23.GetPrincipal(ctx).BlessingStore().Default()
	myBlessing := blessing.String()
	myPerms := testutil.DefaultPerms(myBlessing)
	otherPerms := testutil.DefaultPerms(myBlessing, myBlessing+security.ChainSeparator+"alice")

	// Seed services with same data.
	dbs := util.Databases{
		"db1": util.Database{
			Permissions: myPerms,
			Collections: util.Collections{
				"col1": util.Collection{
					Permissions: otherPerms,
					Rows: util.Rows{
						"key1": "val1",
						"key2": "val2",
						"key3": "val3",
					},
				},
				"col2": util.Collection{
					Permissions: myPerms,
					Rows:        util.Rows{},
				},
			},
		},
		"db2": util.Database{
			Permissions: otherPerms,
			Collections: util.Collections{},
		},
		"db3": util.Database{
			Permissions: otherPerms,
			Collections: util.Collections{
				"col3": util.Collection{
					Permissions: myPerms,
					Rows:        util.Rows{},
				},
				"col4": util.Collection{
					Permissions: otherPerms,
					Rows: util.Rows{
						"key4": "val4",
						"key5": "val5",
						"key6": "val6",
					},
				},
			},
		},
	}
	for _, s := range services {
		if err := util.SeedService(ctx, s, dbs); err != nil {
			t.Fatal(err)
		}
	}

	eq := checker.Equality{}
	if err := eq.Run(ctx, universe); err != nil {
		t.Errorf("expected eq.Run() not to error but got: %v", err)
	}
}

// TestEqualityDifferentRowValues checks that Equality returns an error if the
// syncbases have the same databases and collections, but different row values.
func TestEqualityDifferentRowValues(t *testing.T) {
	// Start two syncbase servers.
	ctx, services, universe, cancel := setupServers(t, 2)
	defer cancel()

	// Seed services with different rows.
	dbs1 := util.Databases{
		"db1": util.Database{
			Collections: util.Collections{
				"col1": util.Collection{
					Rows: util.Rows{
						"key1": "val1",
						"key2": "VAL-TWO", // Different.
						"key3": "val3",
					},
				},
			},
		},
	}
	dbs2 := util.Databases{
		"db1": util.Database{
			Collections: util.Collections{
				"col1": util.Collection{
					Rows: util.Rows{
						"key1": "val1",
						"key2": "DIFFERENT-VAL", // Different.
						"key3": "val3",
					},
				},
			},
		},
	}
	if err := util.SeedService(ctx, services[0], dbs1); err != nil {
		t.Fatal(err)
	}
	if err := util.SeedService(ctx, services[1], dbs2); err != nil {
		t.Fatal(err)
	}

	eq := checker.Equality{}
	if err := eq.Run(ctx, universe); err == nil {
		t.Errorf("expected eq.Run() to error, but it did not")
	}
}

// TestEqualityExtraRows checks that Equality returns an error if the syncbases
// have the same databases and collections, but one has extra rows.
func TestEqualityExtraRows(t *testing.T) {
	// Start two syncbase servers.
	ctx, services, universe, cancel := setupServers(t, 2)
	defer cancel()

	// Seed services with different number of rows.
	dbs1 := util.Databases{
		"db1": util.Database{
			Collections: util.Collections{
				"col1": util.Collection{
					Rows: util.Rows{
						"key1": "val1",
						"key3": "val3",
					},
				},
			},
		},
	}
	dbs2 := util.Databases{
		"db1": util.Database{
			Collections: util.Collections{
				"col1": util.Collection{
					Rows: util.Rows{
						"key1": "val1",
						"key2": "val2", // Missing in above db.
						"key3": "val3",
					},
				},
			},
		},
	}
	if err := util.SeedService(ctx, services[0], dbs1); err != nil {
		t.Fatal(err)
	}
	if err := util.SeedService(ctx, services[1], dbs2); err != nil {
		t.Fatal(err)
	}

	eq := checker.Equality{}
	if err := eq.Run(ctx, universe); err == nil {
		t.Errorf("expected eq.Run() to error but it did not")
	}
}

// TestEqualityDifferentCollections checks that Equality returns an error if
// the syncbases have the same databases and rows but different collection
// names.
func TestEqualityDifferentCollections(t *testing.T) {
	// Start two syncbase servers.
	ctx, services, universe, cancel := setupServers(t, 2)
	defer cancel()

	// Seed services with databases with different collection name.
	dbs1 := util.Databases{
		"db1": util.Database{
			Collections: util.Collections{
				"col1": util.Collection{
					Rows: util.Rows{
						"key1": "val1",
						"key2": "val2",
						"key3": "val3",
					},
				},
			},
		},
	}
	dbs2 := util.Databases{
		"db1": util.Database{
			Collections: util.Collections{
				"col_DIFFERENT": util.Collection{
					Rows: util.Rows{
						"key1": "val1",
						"key2": "val2",
						"key3": "val3",
					},
				},
			},
		},
	}
	if err := util.SeedService(ctx, services[0], dbs1); err != nil {
		t.Fatal(err)
	}
	if err := util.SeedService(ctx, services[1], dbs2); err != nil {
		t.Fatal(err)
	}

	eq := checker.Equality{}
	if err := eq.Run(ctx, universe); err == nil {
		t.Errorf("expected eq.Run() to error but it did not")
	}
}

// TestEqualityDifferentDatabases checks that Equality returns an error if the
// syncbases have the same collections and rows but different database names.
func TestEqualityDifferentDatabases(t *testing.T) {
	// Start two syncbase servers.
	ctx, services, universe, cancel := setupServers(t, 2)
	defer cancel()

	// Seed services with databases with different database name.
	dbs1 := util.Databases{
		"db1": util.Database{
			Collections: util.Collections{
				"col1": util.Collection{
					Rows: util.Rows{
						"key1": "val1",
						"key2": "val2",
						"key3": "val3",
					},
				},
			},
		},
	}
	dbs2 := util.Databases{
		"db_DIFFERENT": util.Database{
			Collections: util.Collections{
				"col1": util.Collection{
					Rows: util.Rows{
						"key1": "val1",
						"key2": "val2",
						"key3": "val3",
					},
				},
			},
		},
	}
	if err := util.SeedService(ctx, services[0], dbs1); err != nil {
		t.Fatal(err)
	}
	if err := util.SeedService(ctx, services[1], dbs2); err != nil {
		t.Fatal(err)
	}

	eq := checker.Equality{}
	if err := eq.Run(ctx, universe); err == nil {
		t.Errorf("expected eq.Run() to error but it did not")
	}
}

// TestEqualityDifferentDatabasePermissions checks that Equality returns an
// error if databases have different Permissions.
func TestEqualityDifferentDatabasePermissions(t *testing.T) {
	// Start two syncbase servers.
	ctx, services, universe, cancel := setupServers(t, 2)
	defer cancel()

	blessing, _ := v23.GetPrincipal(ctx).BlessingStore().Default()
	myBlessing := blessing.String()
	myPerms := testutil.DefaultPerms(myBlessing)
	otherPerms := testutil.DefaultPerms(myBlessing, myBlessing+security.ChainSeparator+"alice")

	// Seed services with databases with different permissions.
	dbs1 := util.Databases{
		"db1": util.Database{
			Permissions: myPerms, // Different.
			Collections: util.Collections{
				"col1": util.Collection{
					Rows: util.Rows{
						"key1": "val1",
						"key2": "val2",
						"key3": "val3",
					},
				},
			},
		},
	}
	dbs2 := util.Databases{
		"db1": util.Database{
			Permissions: otherPerms, // Different.
			Collections: util.Collections{
				"col1": util.Collection{
					Rows: util.Rows{
						"key1": "val1",
						"key2": "val2",
						"key3": "val3",
					},
				},
			},
		},
	}
	if err := util.SeedService(ctx, services[0], dbs1); err != nil {
		t.Fatal(err)
	}
	if err := util.SeedService(ctx, services[1], dbs2); err != nil {
		t.Fatal(err)
	}

	eq := checker.Equality{}
	if err := eq.Run(ctx, universe); err == nil {
		t.Errorf("expected eq.Run() to error but it did not")
	}
}

// TestEqualityDifferentCollectionPermissions checks that Equality returns an
// error if collections have different permissions.
func TestEqualityDifferentCollectionPermissions(t *testing.T) {
	// Start two syncbase servers.
	ctx, services, universe, cancel := setupServers(t, 2)
	defer cancel()

	blessing, _ := v23.GetPrincipal(ctx).BlessingStore().Default()
	myBlessing := blessing.String()
	myPerms := testutil.DefaultPerms(myBlessing)
	otherPerms := testutil.DefaultPerms(myBlessing, myBlessing+security.ChainSeparator+"alice")

	// Seed services with databases with different collection name.
	dbs1 := util.Databases{
		"db1": util.Database{
			Collections: util.Collections{
				"col1": util.Collection{
					Permissions: myPerms, // Different.
					Rows: util.Rows{
						"key1": "val1",
						"key2": "val2",
						"key3": "val3",
					},
				},
			},
		},
	}
	dbs2 := util.Databases{
		"db1": util.Database{
			Collections: util.Collections{
				"col1": util.Collection{
					Permissions: otherPerms, // Different.
					Rows: util.Rows{
						"key1": "val1",
						"key2": "val2",
						"key3": "val3",
					},
				},
			},
		},
	}
	if err := util.SeedService(ctx, services[0], dbs1); err != nil {
		t.Fatal(err)
	}
	if err := util.SeedService(ctx, services[1], dbs2); err != nil {
		t.Fatal(err)
	}

	eq := checker.Equality{}
	if err := eq.Run(ctx, universe); err == nil {
		t.Errorf("expected eq.Run() to error but it did not")
	}
}
