// 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_lite/internal/sbmodel"
	"v.io/x/sensorlog_lite/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)
		}
	}
}
