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

import (
	"reflect"
	"testing"

	"v.io/v23/security"
	"v.io/v23/security/access"
	"v.io/v23/verror"
	_ "v.io/x/ref/runtime/factories/roaming"
	sbtu "v.io/x/ref/services/syncbase/testutil"
	"v.io/x/sensorlog/internal/sbmodel"
	"v.io/x/sensorlog/internal/sbutil"
)

func TestCreateOrOpenDB(t *testing.T) {
	_, ctxOwner, sbName, rootPrincipal, cleanup := sbtu.SetupOrDieCustom("u:one", "u:one:sb", nil)
	defer cleanup()
	ctxGuest := sbtu.NewCtx(ctxOwner, rootPrincipal, "u:two")

	// Try to open (create) db as guest, fail with ErrNoAccess.
	if _, err := sbutil.CreateOrOpenDB(ctxGuest, sbName, sbmodel.MasterCollections); verror.ErrorID(err) != verror.ErrNoAccess.ID {
		t.Errorf("CreateOrOpenDB should have failed with ErrNoAccess, got error: %v", err)
	}
	// Open (create) db as owner.
	dbOwner, err := sbutil.CreateOrOpenDB(ctxOwner, sbName, sbmodel.MasterCollections)
	if err != nil {
		t.Fatalf("CreateOrOpenDB should have succeeded, got error: %v", err)
	}
	// Open db as guest.
	// TODO(ivanpi): Disabled for now. Guest tries (and fails) opening its own
	// collections instead of master's collections.
	/*
		dbGuest, err := sbutil.CreateOrOpenDB(ctxGuest, sbName, sbmodel.MasterCollections)
		if err != nil {
			t.Errorf("CreateOrOpenDB should have succeeded, got error: %v", err)
		}
	*/
	// Expect db permissions with full access for owner, resolve only for others.
	expectPerms := access.Permissions{}.
		Add(security.AllPrincipals, string(access.Resolve)).
		Add(security.BlessingPattern("root:u:one"), string(access.Admin), string(access.Read), string(access.Write))
	if perms, _, err := dbOwner.GetPermissions(ctxOwner); err != nil {
		t.Errorf("GetPermissions should have succeeded, got error: %v", err)
	} else if got, want := perms.Normalize(), expectPerms.Normalize(); !reflect.DeepEqual(got, want) {
		t.Errorf("Unexpected database permissions: got %v, want %v", got, want)
	}
	// Check that all collections exist.
	for _, cs := range sbmodel.MasterCollections {
		c := dbOwner.Collection(ctxOwner, cs.Prototype.Collection())
		if exists, err := c.Exists(ctxOwner); err != nil || !exists {
			t.Errorf("Expected collection %v to exist, got: %v (error: %v)", c.Id(), exists, err)
		}
	}
}

func TestCollectionPermissions(t *testing.T) {
	_, ctxOwner, sbName, _, cleanup := sbtu.SetupOrDieCustom("u:one", "u:one:sb", nil)
	defer cleanup()

	// Open (create) db as owner.
	dbOwner, err := sbutil.CreateOrOpenDB(ctxOwner, sbName, sbmodel.MeasuredCollections)
	if err != nil {
		t.Fatalf("CreateOrOpenDB should have succeeded, got error: %v", err)
	}

	expectPermsFull := access.Permissions{}.
		Add(security.BlessingPattern("root:u:one"), string(access.Admin), string(access.Read), string(access.Write))
	expectPermsReadOnly := access.Permissions{}.
		Add(security.BlessingPattern("root:u:one"), string(access.Admin), string(access.Read))

	// Check that all collections have correct permissions (full or readonly).
	for _, cs := range sbmodel.MeasuredCollections {
		c := dbOwner.Collection(ctxOwner, cs.Prototype.Collection())
		if exists, err := c.Exists(ctxOwner); err != nil || !exists {
			t.Errorf("Expected collection %v to exist, got: %v (error: %v)", c.Id(), exists, err)
		}
		want := expectPermsFull
		if cs.ReadOnly {
			want = expectPermsReadOnly
		}
		if got, err := c.GetPermissions(ctxOwner); err != nil {
			t.Errorf("GetPermissions should have succeeded, got error: %v", err)
		} else if got, want = got.Normalize(), want.Normalize(); !reflect.DeepEqual(got, want) {
			t.Errorf("Unexpected collection %v permissions: got %v, want %v", c.Id(), got, want)
		}
	}
}
