// 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/sbutil"
)

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

	mockTables := []string{"tfoo", "tbar"}

	// Try to open app/db (create both) as guest, fail with ErrNoAccess.
	if _, err := sbutil.CreateOrOpenDB(ctxGuest, sbName, mockTables); 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, mockTables)
	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, mockTables); 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, mockTables); 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, mockTables)
	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, mockTables)
	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, expectPerms; !reflect.DeepEqual(got, want) {
		t.Errorf("Unexpected database permissions: got %v, want %v", got, want)
	}
	// Check that all tables exist.
	for _, tn := range mockTables {
		tb := dbGuest.Table(tn)
		if exists, err := tb.Exists(ctxGuest); err != nil || !exists {
			t.Errorf("Expected table %s to exist, got: %v (error: %v)", tb.Name(), exists, err)
		}
	}
}
