// 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 (
	"bytes"
	"reflect"
	"testing"

	"v.io/v23/security/access"
	"v.io/v23/verror"
	_ "v.io/x/ref/runtime/factories/generic"
	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("one", "one:sb", nil)
	defer cleanup()
	ctxGuest := sbtu.NewCtx(ctxOwner, rootPrincipal, "two")

	// Try to open app/db (create both) as guest, fail with ErrNoAccess.
	if _, err := sbutil.CreateOrOpenDB(ctxGuest, sbName, sbmodel.MasterTables); verror.ErrorID(err) != verror.ErrNoAccess.ID {
		t.Errorf("CreateOrOpenDB should have failed with ErrNoAccess, got error: %v", err)
	}
	// Open app/db (create both) as owner.
	dbOwner, err := sbutil.CreateOrOpenDB(ctxOwner, sbName, sbmodel.MasterTables)
	if err != nil {
		t.Fatalf("CreateOrOpenDB should have succeeded, got error: %v", err)
	}
	// Open existing app/db as guest.
	if _, err := sbutil.CreateOrOpenDB(ctxGuest, sbName, sbmodel.MasterTables); err != nil {
		t.Errorf("CreateOrOpenDB should have succeeded, got error: %v", err)
	}
	// Destroy db (but not app) to simulate interrupted creation.
	if err := dbOwner.Destroy(ctxOwner); err != nil {
		t.Errorf("dbOwner.Destroy should have succeeded, got error: %v", err)
	}
	// Try to open app/db (create db) as guest, fail with ErrNoAccess.
	if _, err := sbutil.CreateOrOpenDB(ctxGuest, sbName, sbmodel.MasterTables); verror.ErrorID(err) != verror.ErrNoAccess.ID {
		t.Errorf("CreateOrOpenDB should have failed with ErrNoAccess, got error: %v", err)
	}
	// Open app/db (recreate db) as owner.
	dbOwner, err = sbutil.CreateOrOpenDB(ctxOwner, sbName, sbmodel.MasterTables)
	if err != nil {
		t.Fatalf("CreateOrOpenDB should have succeeded, got error: %v", err)
	}
	// Open recreated app/db as guest.
	dbGuest, err := sbutil.CreateOrOpenDB(ctxGuest, sbName, sbmodel.MasterTables)
	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, err := access.ReadPermissions(bytes.NewBufferString(`{
		"Admin":{"In":["root:one"]},
		"Read":{"In":["root:one"]},
		"Write":{"In":["root:one"]},
		"Debug":{"In":["root:one"]},
		"Resolve":{"In":["..."]}
	}`))
	if err != nil {
		t.Fatalf("ReadPermissions should have succeeded, got error: %v", err)
	}
	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 tables exist.
	for _, ts := range sbmodel.MasterTables {
		tb := dbGuest.Table(ts.Prototype.Table())
		if exists, err := tb.Exists(ctxGuest); err != nil || !exists {
			t.Errorf("Expected table %s to exist, got: %v (error: %v)", tb.Name(), exists, err)
		}
	}
}

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

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

	expectPermsFull, err := access.ReadPermissions(bytes.NewBufferString(`{
		"Admin":{"In":["root:one"]},
		"Read":{"In":["root:one"]},
		"Write":{"In":["root:one"]},
		"Debug":{"In":["root:one"]},
		"Resolve":{"In":["..."]}
	}`))
	if err != nil {
		t.Fatalf("ReadPermissions should have succeeded, got error: %v", err)
	}
	expectPermsReadOnly, err := access.ReadPermissions(bytes.NewBufferString(`{
		"Admin":{"In":["root:one"]},
		"Read":{"In":["root:one"]},
		"Debug":{"In":["root:one"]},
		"Resolve":{"In":["..."]}
	}`))
	if err != nil {
		t.Fatalf("ReadPermissions should have succeeded, got error: %v", err)
	}

	// Check that all tables have correct permissions (full or readonly).
	for _, ts := range sbmodel.MeasuredTables {
		tb := dbOwner.Table(ts.Prototype.Table())
		if exists, err := tb.Exists(ctxOwner); err != nil || !exists {
			t.Errorf("Expected table %s to exist, got: %v (error: %v)", tb.Name(), exists, err)
		}
		want := expectPermsFull
		if ts.ReadOnly {
			want = expectPermsReadOnly
		}
		if got, err := tb.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 table %s permissions: got %v, want %v", tb.Name(), got, want)
		}
	}
}
