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

import (
	"fmt"
	"os"
	"reflect"
	"syscall"
	"testing"

	"v.io/v23"
	"v.io/v23/security"
	"v.io/v23/security/access"
	"v.io/v23/services/application"
	"v.io/v23/verror"
	"v.io/x/ref/lib/signals"
	appd "v.io/x/ref/services/application/applicationd"
	"v.io/x/ref/services/internal/servicetest"
	"v.io/x/ref/services/repository"
	"v.io/x/ref/test"
	"v.io/x/ref/test/modules"
	"v.io/x/ref/test/testutil"
)

//go:generate v23 test generate

var appRepository = modules.Register(func(env *modules.Env, args ...string) error {
	ctx, shutdown := test.V23Init()
	defer shutdown()

	if len(args) < 2 {
		ctx.Fatalf("repository expected at least name and store arguments and optionally Permissions flags per PermissionsFromFlag")
	}
	publishName := args[0]
	storedir := args[1]

	defer fmt.Fprintf(env.Stdout, "%v terminating\n", publishName)
	defer ctx.VI(1).Infof("%v terminating", publishName)

	dispatcher, err := appd.NewDispatcher(storedir)
	if err != nil {
		ctx.Fatalf("Failed to create repository dispatcher: %v", err)
	}
	ctx, server, err := v23.WithNewDispatchingServer(ctx, publishName, dispatcher)
	if err != nil {
		ctx.Fatalf("NewDispatchingServer(%v) failed: %v", publishName, err)
	}
	ctx.VI(1).Infof("applicationd name: %v", server.Status().Endpoints[0].Name())

	fmt.Fprintf(env.Stdout, "ready:%d\n", os.Getpid())
	<-signals.ShutdownOnSignals(ctx)

	return nil
}, "appRepository")

func TestApplicationUpdatePermissions(t *testing.T) {
	ctx, shutdown := test.V23Init()
	defer shutdown()

	// V23Init sets the context up with a self-signed principal, whose
	// blessing (test-blessing) will act as the root blessing for the test.
	const rootBlessing = test.TestBlessing
	idp := testutil.IDProviderFromPrincipal(v23.GetPrincipal(ctx))
	// Call ourselves test-blessing/self, distinct from test-blessing/other
	// which we'll give to the 'other' context.
	if err := idp.Bless(v23.GetPrincipal(ctx), "self"); err != nil {
		t.Fatal(err)
	}

	sh, deferFn := servicetest.CreateShell(t, ctx, nil)
	defer deferFn()

	// setup mock up directory to put state in
	storedir, cleanup := servicetest.SetupRootDir(t, "application")
	defer cleanup()

	nmh := servicetest.RunCommand(t, sh, nil, appRepository, "repo", storedir)
	pid := servicetest.ReadPID(t, nmh)
	defer syscall.Kill(pid, syscall.SIGINT)

	otherCtx, err := v23.WithPrincipal(ctx, testutil.NewPrincipal())
	if err != nil {
		t.Fatal(err)
	}
	if err := idp.Bless(v23.GetPrincipal(otherCtx), "other"); err != nil {
		t.Fatal(err)
	}

	v1stub := repository.ApplicationClient("repo/search/v1")
	repostub := repository.ApplicationClient("repo")

	// Create example envelopes.
	envelopeV1 := application.Envelope{
		Args:   []string{"--help"},
		Env:    []string{"DEBUG=1"},
		Binary: application.SignedFile{File: "/v23/name/of/binary"},
	}

	// Envelope putting as other should fail.
	if err := v1stub.Put(otherCtx, "base", envelopeV1, false); verror.ErrorID(err) != verror.ErrNoAccess.ID {
		t.Fatalf("Put() returned errorid=%v wanted errorid=%v [%v]", verror.ErrorID(err), verror.ErrNoAccess.ID, err)
	}

	// Envelope putting as global should succeed.
	if err := v1stub.Put(ctx, "base", envelopeV1, false); err != nil {
		t.Fatalf("Put() failed: %v", err)
	}

	ctx.VI(2).Infof("Accessing the Permission Lists of the root returns a (simulated) list providing default authorization.")
	perms, version, err := repostub.GetPermissions(ctx)
	if err != nil {
		t.Fatalf("GetPermissions should not have failed: %v", err)
	}
	if got, want := version, ""; got != want {
		t.Fatalf("GetPermissions got %v, want %v", got, want)
	}
	expected := access.Permissions{
		"Admin": access.AccessList{
			In:    []security.BlessingPattern{test.TestBlessing + "/$", rootBlessing + "/self/$", rootBlessing + "/self/child"},
			NotIn: []string(nil)},
		"Read": access.AccessList{
			In:    []security.BlessingPattern{rootBlessing + "/$", rootBlessing + "/self/$", rootBlessing + "/self/child"},
			NotIn: []string(nil)},
		"Write": access.AccessList{
			In:    []security.BlessingPattern{rootBlessing + "/$", rootBlessing + "/self/$", rootBlessing + "/self/child"},
			NotIn: []string(nil)},
		"Debug": access.AccessList{
			In:    []security.BlessingPattern{rootBlessing + "/$", rootBlessing + "/self/$", rootBlessing + "/self/child"},
			NotIn: []string(nil)},
		"Resolve": access.AccessList{
			In:    []security.BlessingPattern{rootBlessing + "/$", rootBlessing + "/self/$", rootBlessing + "/self/child"},
			NotIn: []string(nil)}}
	if got := perms; !reflect.DeepEqual(expected.Normalize(), got.Normalize()) {
		t.Errorf("got %#v, expected %#v ", got, expected)
	}

	ctx.VI(2).Infof("self attempting to give other permission to update application")
	newPerms := make(access.Permissions)
	for _, tag := range access.AllTypicalTags() {
		newPerms.Add(rootBlessing+"/self", string(tag))
		newPerms.Add(rootBlessing+"/other", string(tag))
	}
	if err := repostub.SetPermissions(ctx, newPerms, ""); err != nil {
		t.Fatalf("SetPermissions failed: %v", err)
	}

	perms, version, err = repostub.GetPermissions(ctx)
	if err != nil {
		t.Fatalf("GetPermissions should not have failed: %v", err)
	}
	expected = newPerms
	if got := perms; !reflect.DeepEqual(expected.Normalize(), got.Normalize()) {
		t.Errorf("got %#v, exected %#v ", got, expected)
	}

	// Envelope putting as other should now succeed.
	if err := v1stub.Put(otherCtx, "base", envelopeV1, true); err != nil {
		t.Fatalf("Put() wrongly failed: %v", err)
	}

	// Other takes control.
	perms, version, err = repostub.GetPermissions(otherCtx)
	if err != nil {
		t.Fatalf("GetPermissions 2 should not have failed: %v", err)
	}
	perms["Admin"] = access.AccessList{
		In:    []security.BlessingPattern{rootBlessing + "/other"},
		NotIn: []string{}}
	if err = repostub.SetPermissions(otherCtx, perms, version); err != nil {
		t.Fatalf("SetPermissions failed: %v", err)
	}

	// Self is now locked out but other isn't.
	if _, _, err = repostub.GetPermissions(ctx); err == nil {
		t.Fatalf("GetPermissions should not have succeeded")
	}
	perms, _, err = repostub.GetPermissions(otherCtx)
	if err != nil {
		t.Fatalf("GetPermissions should not have failed: %v", err)
	}
	expected = access.Permissions{
		"Admin": access.AccessList{
			In:    []security.BlessingPattern{rootBlessing + "/other"},
			NotIn: []string{}},
		"Read": access.AccessList{In: []security.BlessingPattern{rootBlessing + "/other",
			rootBlessing + "/self"},
			NotIn: []string{}},
		"Write": access.AccessList{In: []security.BlessingPattern{rootBlessing + "/other",
			rootBlessing + "/self"},
			NotIn: []string{}},
		"Debug": access.AccessList{In: []security.BlessingPattern{rootBlessing + "/other",
			rootBlessing + "/self"},
			NotIn: []string{}},
		"Resolve": access.AccessList{In: []security.BlessingPattern{rootBlessing + "/other",
			rootBlessing + "/self"},
			NotIn: []string{}}}

	if got := perms; !reflect.DeepEqual(expected.Normalize(), got.Normalize()) {
		t.Errorf("got %#v, exected %#v ", got, expected)
	}
}

func TestPerAppPermissions(t *testing.T) {
	ctx, shutdown := test.V23Init()
	defer shutdown()
	// By default, all principals in this test will have blessings generated based
	// on the username/machine running this process. Give them recognizable names
	// ("root/self" etc.), so the Permissions can be set deterministically.
	idp := testutil.NewIDProvider("root")
	if err := idp.Bless(v23.GetPrincipal(ctx), "self"); err != nil {
		t.Fatal(err)
	}

	sh, deferFn := servicetest.CreateShellAndMountTable(t, ctx, v23.GetPrincipal(ctx))
	defer deferFn()

	// setup mock up directory to put state in
	storedir, cleanup := servicetest.SetupRootDir(t, "application")
	defer cleanup()

	otherCtx, err := v23.WithPrincipal(ctx, testutil.NewPrincipal())
	if err != nil {
		t.Fatal(err)
	}
	if err := idp.Bless(v23.GetPrincipal(otherCtx), "other"); err != nil {
		t.Fatal(err)
	}

	nmh := servicetest.RunCommand(t, sh, nil, appRepository, "repo", storedir)
	pid := servicetest.ReadPID(t, nmh)
	defer syscall.Kill(pid, syscall.SIGINT)

	// Create example envelope.
	envelopeV1 := application.Envelope{
		Args:   []string{"--help"},
		Env:    []string{"DEBUG=1"},
		Binary: application.SignedFile{File: "/v23/name/of/binary"},
	}

	ctx.VI(2).Info("Upload an envelope")
	v1stub := repository.ApplicationClient("repo/search/v1")
	if err := v1stub.Put(ctx, "base", envelopeV1, false); err != nil {
		t.Fatalf("Put() failed: %v", err)
	}
	v2stub := repository.ApplicationClient("repo/search/v2")
	if err := v2stub.Put(ctx, "base", envelopeV1, false); err != nil {
		t.Fatalf("Put() failed: %v", err)
	}
	v3stub := repository.ApplicationClient("repo/naps/v1")
	if err := v3stub.Put(ctx, "base", envelopeV1, false); err != nil {
		t.Fatalf("Put() failed: %v", err)
	}

	ctx.VI(2).Info("Self can access Permissions but other can't.")
	expectedSelfPermissions := access.Permissions{
		"Admin": access.AccessList{
			In:    []security.BlessingPattern{"root/$", "root/self"},
			NotIn: []string{}},
		"Read": access.AccessList{In: []security.BlessingPattern{"root/$", "root/self"},
			NotIn: []string{}},
		"Write": access.AccessList{In: []security.BlessingPattern{"root/$", "root/self"},
			NotIn: []string{}},
		"Debug": access.AccessList{In: []security.BlessingPattern{"root/$", "root/self"},
			NotIn: []string{}},
		"Resolve": access.AccessList{In: []security.BlessingPattern{"root/$", "root/self"},
			NotIn: []string{}}}

	for _, path := range []string{"repo/search", "repo/search/v1", "repo/search/v2", "repo/naps", "repo/naps/v1"} {
		stub := repository.ApplicationClient(path)
		perms, _, err := stub.GetPermissions(ctx)
		if err != nil {
			t.Fatalf("Newly uploaded envelopes failed to receive permission lists: %v", err)
		}

		if got := perms; !reflect.DeepEqual(expectedSelfPermissions.Normalize(), got.Normalize()) {
			t.Errorf("got %#v, expected %#v ", got, expectedSelfPermissions)
		}

		// But otherCtx doesn't have admin permissions so has no access.
		if _, _, err := stub.GetPermissions(otherCtx); err == nil {
			t.Fatalf("GetPermissions didn't fail for other when it should have.")
		}
	}

	ctx.VI(2).Infof("Self sets root Permissions.")
	repostub := repository.ApplicationClient("repo")
	newPerms := make(access.Permissions)
	for _, tag := range access.AllTypicalTags() {
		newPerms.Add("root/self", string(tag))
	}
	if err := repostub.SetPermissions(ctx, newPerms, ""); err != nil {
		t.Fatalf("SetPermissions failed: %v", err)
	}

	ctx.VI(2).Infof("Other still can't access anything.")
	if _, _, err = repostub.GetPermissions(otherCtx); err == nil {
		t.Fatalf("GetPermissions should have failed")
	}

	ctx.VI(2).Infof("Self gives other full access to repo/search/...")
	newPerms, version, err := v1stub.GetPermissions(ctx)
	if err != nil {
		t.Fatalf("GetPermissions should not have failed: %v", err)
	}
	for _, tag := range access.AllTypicalTags() {
		newPerms.Add("root/other", string(tag))
	}
	if err := v1stub.SetPermissions(ctx, newPerms, version); err != nil {
		t.Fatalf("SetPermissions failed: %v", err)
	}

	expected := access.Permissions{
		"Resolve": access.AccessList{In: []security.BlessingPattern{
			"root/$",
			"root/other",
			"root/self"},
			NotIn: []string(nil)},
		"Admin": access.AccessList{In: []security.BlessingPattern{
			"root/$",
			"root/other",
			"root/self"},
			NotIn: []string(nil)},
		"Read": access.AccessList{In: []security.BlessingPattern{
			"root/$",
			"root/other",
			"root/self"},
			NotIn: []string(nil)},
		"Write": access.AccessList{In: []security.BlessingPattern{
			"root/$",
			"root/other",
			"root/self"},
			NotIn: []string(nil)},
		"Debug": access.AccessList{In: []security.BlessingPattern{
			"root/$",
			"root/other", "root/self"},
			NotIn: []string(nil)},
	}

	for _, path := range []string{"repo/search", "repo/search/v1", "repo/search/v2"} {
		stub := repository.ApplicationClient(path)
		ctx.VI(2).Infof("Other can now access this app independent of version.")
		perms, _, err := stub.GetPermissions(otherCtx)
		if err != nil {
			t.Fatalf("GetPermissions should not have failed: %v", err)
		}

		if got := perms; !reflect.DeepEqual(expected.Normalize(), got.Normalize()) {
			t.Errorf("got %#v, expected %#v ", got, expected)
		}
		ctx.VI(2).Infof("Self can also access thanks to hierarchical auth.")
		if _, _, err = stub.GetPermissions(ctx); err != nil {
			t.Fatalf("GetPermissions should not have failed: %v", err)
		}
	}

	ctx.VI(2).Infof("But other locations are unaffected and other cannot access.")
	for _, path := range []string{"repo/naps", "repo/naps/v1"} {
		stub := repository.ApplicationClient(path)
		if _, _, err := stub.GetPermissions(otherCtx); err == nil {
			t.Fatalf("GetPermissions didn't fail when it should have.")
		}
	}

	// Self gives other write perms on base.
	newPerms, version, err = repostub.GetPermissions(ctx)
	if err != nil {
		t.Fatalf("GetPermissions should not have failed: %v", err)
	}
	newPerms["Write"] = access.AccessList{In: []security.BlessingPattern{"root/other", "root/self"}}
	if err := repostub.SetPermissions(ctx, newPerms, version); err != nil {
		t.Fatalf("SetPermissions failed: %v", err)
	}

	// Other can now upload an envelope at both locations.
	for _, stub := range []repository.ApplicationClientStub{v1stub, v2stub} {
		if err := stub.Put(otherCtx, "base", envelopeV1, true); err != nil {
			t.Fatalf("Put() failed: %v", err)
		}
	}

	// But because application search already exists, the Permissions do not change.
	for _, path := range []string{"repo/search", "repo/search/v1", "repo/search/v2"} {
		stub := repository.ApplicationClient(path)
		perms, _, err := stub.GetPermissions(otherCtx)
		if err != nil {
			t.Fatalf("GetPermissions should not have failed: %v", err)
		}
		if got := perms; !reflect.DeepEqual(expected.Normalize(), got.Normalize()) {
			t.Errorf("got %#v, expected %#v ", got, expected)
		}
	}

	// But self didn't give other Permissions modification permissions.
	for _, path := range []string{"repo/search", "repo/search/v2"} {
		stub := repository.ApplicationClient(path)
		if _, _, err := stub.GetPermissions(otherCtx); err != nil {
			t.Fatalf("GetPermissions failed when it should not have for same application: %v", err)
		}
	}
}
