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

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

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/naming"
	"v.io/v23/security"
	"v.io/v23/security/access"
	"v.io/v23/services/repository"
	"v.io/v23/verror"
	"v.io/x/lib/vlog"
	vsecurity "v.io/x/ref/lib/security"
	"v.io/x/ref/lib/signals"
	"v.io/x/ref/services/internal/binarylib"
	"v.io/x/ref/services/internal/servicetest"
	"v.io/x/ref/test"
	"v.io/x/ref/test/modules"
	"v.io/x/ref/test/testutil"
)

//go:generate v23 test generate

var binaryd = modules.Register(func(env *modules.Env, args ...string) error {
	if len(args) < 2 {
		vlog.Fatalf("binaryd expected at least name and store arguments and optionally AccessList flags per PermissionsFromFlag")
	}
	publishName := args[0]
	storedir := args[1]

	ctx, shutdown := test.V23Init()

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

	server, endpoint := servicetest.NewServer(ctx)
	name := naming.JoinAddressName(endpoint, "")
	vlog.VI(1).Infof("binaryd name: %v", name)

	depth := 2
	state, err := binarylib.NewState(storedir, "", depth)
	if err != nil {
		vlog.Fatalf("NewState(%v, %v, %v) failed: %v", storedir, "", depth, err)
	}
	dispatcher, err := binarylib.NewDispatcher(v23.GetPrincipal(ctx), state)
	if err != nil {
		vlog.Fatalf("Failed to create binaryd dispatcher: %v", err)
	}
	if err := server.ServeDispatcher(publishName, dispatcher); err != nil {
		vlog.Fatalf("Serve(%v) failed: %v", publishName, err)
	}

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

	return nil
}, "binaryd")

func b(name string) repository.BinaryClientStub {
	return repository.BinaryClient(name)
}

func ctxWithBlessedPrincipal(ctx *context.T, childExtension string) (*context.T, error) {
	parent := v23.GetPrincipal(ctx)
	child := testutil.NewPrincipal()
	b, err := parent.Bless(child.PublicKey(), parent.BlessingStore().Default(), childExtension, security.UnconstrainedUse())
	if err != nil {
		return nil, err
	}
	if err := vsecurity.SetDefaultBlessings(child, b); err != nil {
		return nil, err
	}
	return v23.WithPrincipal(ctx, child)
}

func TestBinaryCreateAccessList(t *testing.T) {
	ctx, shutdown := test.V23Init()
	defer shutdown()
	v23.GetNamespace(ctx).CacheCtl(naming.DisableCache(true))

	selfCtx, err := v23.WithPrincipal(ctx, testutil.NewPrincipal("self"))
	if err != nil {
		t.Fatalf("WithPrincipal failed: %v", err)
	}
	childCtx, err := ctxWithBlessedPrincipal(selfCtx, "child")
	if err != nil {
		t.Fatalf("WithPrincipal failed: %v", err)
	}

	sh, deferFn := servicetest.CreateShellAndMountTable(t, childCtx, v23.GetPrincipal(childCtx))
	defer deferFn()
	// make selfCtx and childCtx have the same Namespace Roots as set by
	// CreateShellAndMountTable
	v23.GetNamespace(selfCtx).SetRoots(v23.GetNamespace(childCtx).Roots()...)

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

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

	vlog.VI(2).Infof("Self uploads a shared and private binary.")
	if err := b("bini/private").Create(childCtx, 1, repository.MediaInfo{Type: "application/octet-stream"}); err != nil {
		t.Fatalf("Create() failed %v", err)
	}
	fakeDataPrivate := testData()
	if streamErr, err := invokeUpload(t, childCtx, b("bini/private"), fakeDataPrivate, 0); streamErr != nil || err != nil {
		t.Fatalf("invokeUpload() failed %v, %v", err, streamErr)
	}

	vlog.VI(2).Infof("Validate that the AccessList also allows Self")
	perms, _, err := b("bini/private").GetPermissions(selfCtx)
	if err != nil {
		t.Fatalf("GetPermissions failed: %v", err)
	}
	expected := access.Permissions{
		"Admin":   access.AccessList{In: []security.BlessingPattern{"self/$", "self/child"}},
		"Read":    access.AccessList{In: []security.BlessingPattern{"self/$", "self/child"}},
		"Write":   access.AccessList{In: []security.BlessingPattern{"self/$", "self/child"}},
		"Debug":   access.AccessList{In: []security.BlessingPattern{"self/$", "self/child"}},
		"Resolve": access.AccessList{In: []security.BlessingPattern{"self/$", "self/child"}},
	}
	if got, want := perms.Normalize(), expected.Normalize(); !reflect.DeepEqual(got, want) {
		t.Errorf("got %#v, expected %#v ", got, want)
	}
}

func TestBinaryRootAccessList(t *testing.T) {
	ctx, shutdown := test.V23Init()
	defer shutdown()
	v23.GetNamespace(ctx).CacheCtl(naming.DisableCache(true))

	selfPrincipal := testutil.NewPrincipal("self")
	selfCtx, err := v23.WithPrincipal(ctx, selfPrincipal)
	if err != nil {
		t.Fatalf("WithPrincipal failed: %v", err)
	}
	sh, deferFn := servicetest.CreateShellAndMountTable(t, selfCtx, v23.GetPrincipal(selfCtx))
	defer deferFn()

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

	otherPrincipal := testutil.NewPrincipal("other")
	if err := otherPrincipal.AddToRoots(selfPrincipal.BlessingStore().Default()); err != nil {
		t.Fatalf("otherPrincipal.AddToRoots() failed: %v", err)
	}
	otherCtx, err := v23.WithPrincipal(selfCtx, otherPrincipal)
	if err != nil {
		t.Fatalf("WithPrincipal() failed: %v", err)
	}

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

	vlog.VI(2).Infof("Self uploads a shared and private binary.")
	if err := b("bini/private").Create(selfCtx, 1, repository.MediaInfo{Type: "application/octet-stream"}); err != nil {
		t.Fatalf("Create() failed %v", err)
	}
	fakeDataPrivate := testData()
	if streamErr, err := invokeUpload(t, selfCtx, b("bini/private"), fakeDataPrivate, 0); streamErr != nil || err != nil {
		t.Fatalf("invokeUpload() failed %v, %v", err, streamErr)
	}

	if err := b("bini/shared").Create(selfCtx, 1, repository.MediaInfo{Type: "application/octet-stream"}); err != nil {
		t.Fatalf("Create() failed %v", err)
	}
	fakeDataShared := testData()
	if streamErr, err := invokeUpload(t, selfCtx, b("bini/shared"), fakeDataShared, 0); streamErr != nil || err != nil {
		t.Fatalf("invokeUpload() failed %v, %v", err, streamErr)
	}

	vlog.VI(2).Infof("Verify that in the beginning other can't access bini/private or bini/shared")
	if _, _, err := b("bini/private").Stat(otherCtx); verror.ErrorID(err) != verror.ErrNoAccess.ID {
		t.Fatalf("Stat() should have failed but didn't: %v", err)
	}
	if _, _, err := b("bini/shared").Stat(otherCtx); verror.ErrorID(err) != verror.ErrNoAccess.ID {
		t.Fatalf("Stat() should have failed but didn't: %v", err)
	}

	vlog.VI(2).Infof("Validate the AccessList file on bini/private.")
	perms, _, err := b("bini/private").GetPermissions(selfCtx)
	if err != nil {
		t.Fatalf("GetPermissions failed: %v", err)
	}
	expected := access.Permissions{
		"Admin":   access.AccessList{In: []security.BlessingPattern{"self"}},
		"Read":    access.AccessList{In: []security.BlessingPattern{"self"}},
		"Write":   access.AccessList{In: []security.BlessingPattern{"self"}},
		"Debug":   access.AccessList{In: []security.BlessingPattern{"self"}},
		"Resolve": access.AccessList{In: []security.BlessingPattern{"self"}},
	}
	if got, want := perms.Normalize(), expected.Normalize(); !reflect.DeepEqual(got, want) {
		t.Errorf("got %#v, expected %#v ", got, want)
	}

	vlog.VI(2).Infof("Validate the AccessList file on bini/private.")
	perms, version, err := b("bini/private").GetPermissions(selfCtx)
	if err != nil {
		t.Fatalf("GetPermissions failed: %v", err)
	}
	if got, want := perms.Normalize(), expected.Normalize(); !reflect.DeepEqual(got, want) {
		t.Errorf("got %#v, expected %#v ", got, want)
	}

	vlog.VI(2).Infof("self blesses other as self/other and locks the bini/private binary to itself.")
	selfBlessing := selfPrincipal.BlessingStore().Default()
	otherBlessing, err := selfPrincipal.Bless(otherPrincipal.PublicKey(), selfBlessing, "other", security.UnconstrainedUse())
	if err != nil {
		t.Fatalf("selfPrincipal.Bless() failed: %v", err)
	}
	if _, err := otherPrincipal.BlessingStore().Set(otherBlessing, security.AllPrincipals); err != nil {
		t.Fatalf("otherPrincipal.BlessingStore() failed: %v", err)
	}

	vlog.VI(2).Infof("Self modifies the AccessList file on bini/private.")
	for _, tag := range access.AllTypicalTags() {
		perms.Clear("self", string(tag))
		perms.Add("self/$", string(tag))
	}
	if err := b("bini/private").SetPermissions(selfCtx, perms, version); err != nil {
		t.Fatalf("SetPermissions failed: %v", err)
	}

	vlog.VI(2).Infof(" Verify that bini/private's perms are updated.")
	updated := access.Permissions{
		"Admin":   access.AccessList{In: []security.BlessingPattern{"self/$"}},
		"Read":    access.AccessList{In: []security.BlessingPattern{"self/$"}},
		"Write":   access.AccessList{In: []security.BlessingPattern{"self/$"}},
		"Debug":   access.AccessList{In: []security.BlessingPattern{"self/$"}},
		"Resolve": access.AccessList{In: []security.BlessingPattern{"self/$"}},
	}
	perms, _, err = b("bini/private").GetPermissions(selfCtx)
	if err != nil {
		t.Fatalf("GetPermissions failed: %v", err)
	}
	if got, want := perms.Normalize(), updated.Normalize(); !reflect.DeepEqual(got, want) {
		t.Errorf("got %#v, expected %#v ", got, want)
	}

	// Other still can't access bini/shared because there's no AccessList file at the
	// root level. Self has to set one explicitly to enable sharing. This way, self
	// can't accidentally expose the server without setting a root AccessList.
	vlog.VI(2).Infof(" Verify that other still can't access bini/shared.")
	if _, _, err := b("bini/shared").Stat(otherCtx); verror.ErrorID(err) != verror.ErrNoAccess.ID {
		t.Fatalf("Stat() should have failed but didn't: %v", err)
	}

	vlog.VI(2).Infof("Self sets a root AccessList.")
	newRootAccessList := make(access.Permissions)
	for _, tag := range access.AllTypicalTags() {
		newRootAccessList.Add("self/$", string(tag))
	}
	if err := b("bini").SetPermissions(selfCtx, newRootAccessList, ""); err != nil {
		t.Fatalf("SetPermissions failed: %v", err)
	}

	vlog.VI(2).Infof("Verify that other can access bini/shared now but not access bini/private.")
	if _, _, err := b("bini/shared").Stat(otherCtx); err != nil {
		t.Fatalf("Stat() shouldn't have failed: %v", err)
	}
	if _, _, err := b("bini/private").Stat(otherCtx); verror.ErrorID(err) != verror.ErrNoAccess.ID {
		t.Fatalf("Stat() should have failed but didn't: %v", err)
	}

	vlog.VI(2).Infof("Other still can't create so Self gives Other right to Create.")
	perms, tag, err := b("bini").GetPermissions(selfCtx)
	if err != nil {
		t.Fatalf("GetPermissions() failed: %v", err)
	}

	// More than one AccessList change will result in the same functional result in
	// this test: that self/other acquires the right to invoke Create at the
	// root. In particular:
	//
	// a. perms.Add("self", "Write ")
	// b. perms.Add("self/other", "Write")
	// c. perms.Add("self/other/$", "Write")
	//
	// will all give self/other the right to invoke Create but in the case of
	// (a) it will also extend this right to self's delegates (because of the
	// absence of the $) including other and in (b) will also extend the
	// Create right to all of other's delegates. Since (c) is the minimum
	// case, use that.
	perms.Add("self/other/$", string("Write"))
	err = b("bini").SetPermissions(selfCtx, perms, tag)
	if err != nil {
		t.Fatalf("SetPermissions() failed: %v", err)
	}

	vlog.VI(2).Infof("Other creates bini/otherbinary")
	if err := b("bini/otherbinary").Create(otherCtx, 1, repository.MediaInfo{Type: "application/octet-stream"}); err != nil {
		t.Fatalf("Create() failed %v", err)
	}
	fakeDataOther := testData()
	if streamErr, err := invokeUpload(t, otherCtx, b("bini/otherbinary"), fakeDataOther, 0); streamErr != nil || err != nil {
		t.FailNow()
	}

	vlog.VI(2).Infof("Other can read perms for bini/otherbinary.")
	updated = access.Permissions{
		"Admin":   access.AccessList{In: []security.BlessingPattern{"self/$", "self/other"}},
		"Read":    access.AccessList{In: []security.BlessingPattern{"self/$", "self/other"}},
		"Write":   access.AccessList{In: []security.BlessingPattern{"self/$", "self/other"}},
		"Debug":   access.AccessList{In: []security.BlessingPattern{"self/$", "self/other"}},
		"Resolve": access.AccessList{In: []security.BlessingPattern{"self/$", "self/other"}},
	}
	perms, _, err = b("bini/otherbinary").GetPermissions(otherCtx)
	if err != nil {
		t.Fatalf("GetPermissions failed: %v", err)
	}
	if got, want := perms.Normalize(), updated.Normalize(); !reflect.DeepEqual(want, got) {
		t.Errorf("got %#v, expected %#v ", got, want)
	}

	vlog.VI(2).Infof("Other tries to exclude self by removing self from the AccessList set")
	perms, tag, err = b("bini/otherbinary").GetPermissions(otherCtx)
	if err != nil {
		t.Fatalf("GetPermissions() failed: %v", err)
	}
	perms.Clear("self/$")
	err = b("bini/otherbinary").SetPermissions(otherCtx, perms, tag)
	if err != nil {
		t.Fatalf("SetPermissions() failed: %v", err)
	}

	vlog.VI(2).Infof("Verify that other can make this change.")
	updated = access.Permissions{
		"Admin":   access.AccessList{In: []security.BlessingPattern{"self/other"}},
		"Read":    access.AccessList{In: []security.BlessingPattern{"self/other"}},
		"Write":   access.AccessList{In: []security.BlessingPattern{"self/other"}},
		"Debug":   access.AccessList{In: []security.BlessingPattern{"self/other"}},
		"Resolve": access.AccessList{In: []security.BlessingPattern{"self/other"}},
	}
	perms, _, err = b("bini/otherbinary").GetPermissions(otherCtx)
	if err != nil {
		t.Fatalf("GetPermissions failed: %v", err)
	}
	if got, want := perms.Normalize(), updated.Normalize(); !reflect.DeepEqual(want, got) {
		t.Errorf("got %#v, expected %#v ", got, want)
	}

	vlog.VI(2).Infof("But self's rights are inherited from root so self can still access despite this.")
	if _, _, err := b("bini/otherbinary").Stat(selfCtx); err != nil {
		t.Fatalf("Stat() shouldn't have failed: %v", err)
	}

	vlog.VI(2).Infof("Self petulantly blacklists other back.")
	perms, tag, err = b("bini").GetPermissions(selfCtx)
	if err != nil {
		t.Fatalf("GetPermissions() failed: %v", err)
	}
	for _, tag := range access.AllTypicalTags() {
		perms.Blacklist("self/other", string(tag))
	}
	err = b("bini").SetPermissions(selfCtx, perms, tag)
	if err != nil {
		t.Fatalf("SetPermissions() failed: %v", err)
	}

	vlog.VI(2).Infof("And now other can do nothing at affecting the root. Other should be penitent.")
	if err := b("bini/nototherbinary").Create(otherCtx, 1, repository.MediaInfo{Type: "application/octet-stream"}); verror.ErrorID(err) != verror.ErrNoAccess.ID {
		t.Fatalf("Create() should have failed %v", err)
	}

	vlog.VI(2).Infof("But other can still access shared.")
	if _, _, err := b("bini/shared").Stat(otherCtx); err != nil {
		t.Fatalf("Stat() should not have failed but did: %v", err)
	}

	vlog.VI(2).Infof("Self petulantly blacklists other's binary too.")
	perms, tag, err = b("bini/shared").GetPermissions(selfCtx)
	if err != nil {
		t.Fatalf("GetPermissions() failed: %v", err)
	}
	for _, tag := range access.AllTypicalTags() {
		perms.Blacklist("self/other", string(tag))
	}
	err = b("bini/shared").SetPermissions(selfCtx, perms, tag)
	if err != nil {
		t.Fatalf("SetPermissions() failed: %v", err)
	}
	vlog.VI(2).Infof("And now other can't access shared either.")
	if _, _, err := b("bini/shared").Stat(otherCtx); verror.ErrorID(err) != verror.ErrNoAccess.ID {
		t.Fatalf("Stat() should have failed but didn't: %v", err)
	}
	// TODO(rjkroege): Extend the test with a third principal and verify that
	// new principals can be given Admin perimission at the root.

	vlog.VI(2).Infof("Self feels guilty for petulance and disempowers itself")
	// TODO(rjkroege,caprita): This is a one-way transition for self. Perhaps it
	// should not be. Consider adding a factory-reset facility.
	perms, tag, err = b("bini").GetPermissions(selfCtx)
	if err != nil {
		t.Fatalf("GetPermissions() failed: %v", err)
	}
	perms.Clear("self/$", "Admin")
	err = b("bini").SetPermissions(selfCtx, perms, tag)
	if err != nil {
		t.Fatalf("SetPermissions() failed: %v", err)
	}

	vlog.VI(2).Info("Self can't access other's binary now")
	if _, _, err := b("bini/otherbinary").Stat(selfCtx); err == nil {
		t.Fatalf("Stat() should have failed but didn't")
	}
}

func TestBinaryRationalStartingValueForGetPermissions(t *testing.T) {
	ctx, shutdown := test.V23Init()
	defer shutdown()
	v23.GetNamespace(ctx).CacheCtl(naming.DisableCache(true))

	selfPrincipal := testutil.NewPrincipal("self")
	selfCtx, err := v23.WithPrincipal(ctx, selfPrincipal)
	if err != nil {
		t.Fatalf("WithPrincipal failed: %v", err)
	}
	sh, deferFn := servicetest.CreateShellAndMountTable(t, selfCtx, v23.GetPrincipal(selfCtx))
	defer deferFn()

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

	otherPrincipal := testutil.NewPrincipal("other")
	if err := otherPrincipal.AddToRoots(selfPrincipal.BlessingStore().Default()); err != nil {
		t.Fatalf("otherPrincipal.AddToRoots() failed: %v", err)
	}

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

	perms, tag, err := b("bini").GetPermissions(selfCtx)
	if err != nil {
		t.Fatalf("GetPermissions failed: %#v", err)
	}
	expected := access.Permissions{
		"Admin":   access.AccessList{In: []security.BlessingPattern{"self/$", "self/child"}, NotIn: []string{}},
		"Read":    access.AccessList{In: []security.BlessingPattern{"self/$", "self/child"}, NotIn: []string{}},
		"Write":   access.AccessList{In: []security.BlessingPattern{"self/$", "self/child"}, NotIn: []string{}},
		"Debug":   access.AccessList{In: []security.BlessingPattern{"self/$", "self/child"}, NotIn: []string{}},
		"Resolve": access.AccessList{In: []security.BlessingPattern{"self/$", "self/child"}, NotIn: []string{}},
	}
	if got, want := perms.Normalize(), expected.Normalize(); !reflect.DeepEqual(got, want) {
		t.Errorf("got %#v, expected %#v ", got, want)
	}

	perms.Blacklist("self", string("Read"))
	err = b("bini").SetPermissions(selfCtx, perms, tag)
	if err != nil {
		t.Fatalf("SetPermissions() failed: %v", err)
	}

	perms, tag, err = b("bini").GetPermissions(selfCtx)
	if err != nil {
		t.Fatalf("GetPermissions failed: %#v", err)
	}
	expected = access.Permissions{
		"Admin":   access.AccessList{In: []security.BlessingPattern{"self/$", "self/child"}, NotIn: []string{}},
		"Read":    access.AccessList{In: []security.BlessingPattern{"self/$", "self/child"}, NotIn: []string{"self"}},
		"Write":   access.AccessList{In: []security.BlessingPattern{"self/$", "self/child"}, NotIn: []string{}},
		"Debug":   access.AccessList{In: []security.BlessingPattern{"self/$", "self/child"}, NotIn: []string{}},
		"Resolve": access.AccessList{In: []security.BlessingPattern{"self/$", "self/child"}, NotIn: []string{}},
	}
	if got, want := perms.Normalize(), expected.Normalize(); !reflect.DeepEqual(got, want) {
		t.Errorf("got %#v, expected %#v ", got, want)
	}

}
