// 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 namespace_test

import (
	"fmt"
	"reflect"
	"testing"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/naming"
	"v.io/v23/rpc"
	"v.io/v23/security"
	"v.io/v23/security/access"

	"v.io/x/ref/lib/xrpc"
	_ "v.io/x/ref/runtime/factories/generic"
	"v.io/x/ref/services/mounttable/mounttablelib"
	"v.io/x/ref/test"
	"v.io/x/ref/test/testutil"
)

func init() {
	test.Init()
}

func initTest() (rootCtx *context.T, aliceCtx *context.T, bobCtx *context.T, shutdown v23.Shutdown) {
	ctx, shutdown := test.V23Init()
	var err error
	if rootCtx, err = v23.WithPrincipal(ctx, testutil.NewPrincipal("root")); err != nil {
		panic("failed to set root principal")
	}
	if aliceCtx, err = v23.WithPrincipal(ctx, testutil.NewPrincipal("alice")); err != nil {
		panic("failed to set alice principal")
	}
	if bobCtx, err = v23.WithPrincipal(ctx, testutil.NewPrincipal("bob")); err != nil {
		panic("failed to set bob principal")
	}
	for _, r := range []*context.T{rootCtx, aliceCtx, bobCtx} {
		// A hack to set the namespace roots to a value that won't work.
		v23.GetNamespace(r).SetRoots()
		// And have all principals recognize each others blessings.
		p1 := v23.GetPrincipal(r)
		for _, other := range []*context.T{rootCtx, aliceCtx, bobCtx} {
			// testutil.NewPrincipal has already setup each
			// principal to use the same blessing for both server
			// and client activities.
			if err := p1.AddToRoots(v23.GetPrincipal(other).BlessingStore().Default()); err != nil {
				panic(err)
			}
		}
	}
	return rootCtx, aliceCtx, bobCtx, shutdown
}

// Create a new mounttable service.
func newMT(t *testing.T, ctx *context.T) (func(), string) {
	estr, stopFunc, err := mounttablelib.StartServers(ctx, v23.GetListenSpec(ctx), "", "", "", "", "mounttable")
	if err != nil {
		t.Fatalf("r.NewServer: %s", err)
	}
	return stopFunc, estr
}

type nopServer struct{ x int }

func (s *nopServer) NOP(*context.T, rpc.ServerCall) error {
	return nil
}

var nobody = []security.BlessingPattern{""}
var everybody = []security.BlessingPattern{"..."}
var closedPerms = access.Permissions{
	"Resolve": access.AccessList{
		In: nobody,
	},
	"Read": access.AccessList{
		In: nobody,
	},
	"Admin": access.AccessList{
		In: nobody,
	},
	"Create": access.AccessList{
		In: nobody,
	},
	"Mount": access.AccessList{
		In: nobody,
	},
}
var closedPermsWithOwnerAdded = access.Permissions{
	"Resolve": access.AccessList{
		In: nobody,
	},
	"Read": access.AccessList{
		In: nobody,
	},
	"Admin": access.AccessList{
		In: []security.BlessingPattern{"", "root"},
	},
	"Create": access.AccessList{
		In: nobody,
	},
	"Mount": access.AccessList{
		In: nobody,
	},
}
var openPerms = access.Permissions{
	"Resolve": access.AccessList{
		In: everybody,
	},
	"Read": access.AccessList{
		In: everybody,
	},
	"Admin": access.AccessList{
		In: everybody,
	},
	"Create": access.AccessList{
		In: everybody,
	},
	"Mount": access.AccessList{
		In: everybody,
	},
}

func TestPermissions(t *testing.T) {
	// Create three different personalities.
	// TODO(p): Use the multiple personalities to test Permissions functionality.
	rootCtx, aliceCtx, _, shutdown := initTest()
	defer shutdown()

	// Create root mounttable.
	stop, rmtAddr := newMT(t, rootCtx)
	fmt.Printf("rmt at %s\n", rmtAddr)
	defer stop()
	ns := v23.GetNamespace(rootCtx)
	ns.SetRoots("/" + rmtAddr)

	// Create two parallel mount tables.
	stop1, mt1Addr := newMT(t, rootCtx)
	fmt.Printf("mt1 at %s\n", mt1Addr)
	defer stop1()
	stop2, mt2Addr := newMT(t, rootCtx)
	fmt.Printf("mt2 at %s\n", mt2Addr)
	defer stop2()

	// Mount them into the root.
	if err := ns.Mount(rootCtx, "a/b/c", mt1Addr, 0, naming.ServesMountTable(true)); err != nil {
		t.Fatalf("Failed to Mount %s onto a/b/c: %s", "/"+mt1Addr, err)
	}
	if err := ns.Mount(rootCtx, "a/b/c", mt2Addr, 0, naming.ServesMountTable(true)); err != nil {
		t.Fatalf("Failed to Mount %s onto a/b/c: %s", "/"+mt2Addr, err)
	}

	// Set/Get the mount point's Permissions.
	perms, version, err := ns.GetPermissions(rootCtx, "a/b/c")
	if err != nil {
		t.Fatalf("GetPermissions a/b/c: %s", err)
	}
	if err := ns.SetPermissions(rootCtx, "a/b/c", openPerms, version); err != nil {
		t.Fatalf("SetPermissions a/b/c: %s", err)
	}
	nacl, _, err := ns.GetPermissions(rootCtx, "a/b/c")
	if err != nil {
		t.Fatalf("GetPermissions a/b/c: %s", err)
	}
	if !reflect.DeepEqual(openPerms, nacl) {
		t.Fatalf("want %v, got %v", openPerms, nacl)
	}

	// Now Set/Get the parallel mount point's Permissions.
	name := "a/b/c/d/e"
	version = "" // Parallel setperms with any other value is dangerous
	if err := ns.SetPermissions(rootCtx, name, openPerms, version); err != nil {
		t.Fatalf("SetPermissions %s: %s", name, err)
	}
	nacl, _, err = ns.GetPermissions(rootCtx, name)
	if err != nil {
		t.Fatalf("GetPermissions %s: %s", name, err)
	}
	if !reflect.DeepEqual(openPerms, nacl) {
		t.Fatalf("want %v, got %v", openPerms, nacl)
	}

	// Get from each server individually to make sure both are set.
	name = naming.Join(mt1Addr, "d/e")
	nacl, _, err = ns.GetPermissions(rootCtx, name)
	if err != nil {
		t.Fatalf("GetPermissions %s: %s", name, err)
	}
	if !reflect.DeepEqual(openPerms, nacl) {
		t.Fatalf("want %v, got %v", openPerms, nacl)
	}
	name = naming.Join(mt2Addr, "d/e")
	nacl, _, err = ns.GetPermissions(rootCtx, name)
	if err != nil {
		t.Fatalf("GetPermissions %s: %s", name, err)
	}
	if !reflect.DeepEqual(openPerms, nacl) {
		t.Fatalf("want %v, got %v", perms, nacl)
	}

	// Create mount points accessible only by root's key and owner.
	name = "a/b/c/d/f"
	deadbody := "/the:8888/rain"
	if err := ns.SetPermissions(rootCtx, name, closedPerms, version); err != nil {
		t.Fatalf("SetPermissions %s: %s", name, err)
	}
	nacl, _, err = ns.GetPermissions(rootCtx, name)
	if err != nil {
		t.Fatalf("GetPermissions %s: %s", name, err)
	}
	if !reflect.DeepEqual(closedPermsWithOwnerAdded, nacl) {
		t.Fatalf("want %v, got %v", closedPermsWithOwnerAdded, nacl)
	}
	if err := ns.Mount(rootCtx, name, deadbody, 10000); err != nil {
		t.Fatalf("Mount %s: %s", name, err)
	}

	// Alice shouldn't be able to resolve it.
	_, err = v23.GetNamespace(aliceCtx).Resolve(aliceCtx, name)
	if err == nil {
		t.Fatalf("as alice we shouldn't be able to Resolve %s", name)
	}

	// Root should be able to resolve it.
	_, err = ns.Resolve(rootCtx, name)
	if err != nil {
		t.Fatalf("as root Resolve %s: %s", name, err)
	}

	// Create a mount point via Serve accessible only by root's key and owner.
	name = "a/b/c/d/g"
	if err := ns.SetPermissions(rootCtx, name, closedPerms, version); err != nil {
		t.Fatalf("SetPermissions %s: %s", name, err)
	}
	if _, err := xrpc.NewServer(rootCtx, name, &nopServer{1}, nil); err != nil {
		t.Fatalf("v23.NewServer failed: %v", err)
	}
	// Alice shouldn't be able to resolve it.
	_, err = v23.GetNamespace(aliceCtx).Resolve(aliceCtx, name)
	if err == nil {
		t.Fatalf("as alice we shouldn't be able to Resolve %s", name)
	}

	// Root should be able to resolve it.
	resolveWithRetry(rootCtx, name)
}
