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

import (
	"fmt"
	"testing"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/rpc"
	"v.io/v23/security"
	"v.io/v23/vdl"

	_ "v.io/x/ref/runtime/factories/generic"
	"v.io/x/ref/test"
)

const topLevelName = "mock-blesser"

type mockBlesserService struct {
	p     security.Principal
	count int
}

func newMockBlesserService(p security.Principal) *mockBlesserService {
	return &mockBlesserService{
		p:     p,
		count: 0,
	}
}

func (m *mockBlesserService) BlessUsingAccessToken(c *context.T, accessToken string, co ...rpc.CallOpt) (security.Blessings, string, error) {
	m.count++
	name := fmt.Sprintf("%s%s%d", topLevelName, security.ChainSeparator, m.count)
	blessing, err := m.p.BlessSelf(name)
	if err != nil {
		return blessing, "", err
	}
	return blessing, name, nil
}

func setup(t *testing.T) (*Browspr, func()) {
	ctx, shutdown := test.V23Init()

	spec := v23.GetListenSpec(ctx)
	spec.Proxy = "/mock/proxy"
	mockPostMessage := func(_ int32, _, _ string) {}
	browspr := NewBrowspr(ctx, mockPostMessage, &spec, "/mock:1234/identd", nil)
	principal := v23.GetPrincipal(browspr.ctx)
	browspr.accountManager.SetMockBlesser(newMockBlesserService(principal))

	return browspr, func() {
		browspr.Shutdown()
		shutdown()
	}
}

func TestHandleCreateAccount(t *testing.T) {
	browspr, teardown := setup(t)
	defer teardown()

	// Verify that HandleAuthGetAccountsRpc returns empty.
	nilValue := vdl.ValueOf(GetAccountsMessage{})
	a, err := browspr.HandleAuthGetAccountsRpc(nilValue)
	if err != nil {
		t.Fatalf("browspr.HandleAuthGetAccountsRpc(%v) failed: %v", nilValue, err)
	}
	if a.Len() > 0 {
		t.Fatalf("Expected accounts to be empty array but got %v", a)
	}

	// Add one account.
	message1 := vdl.ValueOf(CreateAccountMessage{
		Token: "mock-access-token-1",
	})
	account1, err := browspr.HandleAuthCreateAccountRpc(message1)
	if err != nil {
		t.Fatalf("browspr.HandleAuthCreateAccountRpc(%v) failed: %v", message1, err)
	}

	// Verify that principalManager has the new account
	if b, err := browspr.principalManager.BlessingsForAccount(account1.RawString()); err != nil || b.IsZero() {
		t.Fatalf("Failed to get Blessings for account %v: got %v, %v", account1, b, err)
	}

	// Verify that HandleAuthGetAccountsRpc returns the new account.
	gotAccounts1, err := browspr.HandleAuthGetAccountsRpc(nilValue)
	if err != nil {
		t.Fatalf("browspr.HandleAuthGetAccountsRpc(%v) failed: %v", nilValue, err)
	}
	if want := vdl.ValueOf([]string{account1.RawString()}); !vdl.EqualValue(want, gotAccounts1) {
		t.Fatalf("Expected account to be %v but got empty but got %v", want, gotAccounts1)
	}

	// Add another account
	message2 := vdl.ValueOf(CreateAccountMessage{
		Token: "mock-access-token-2",
	})
	account2, err := browspr.HandleAuthCreateAccountRpc(message2)
	if err != nil {
		t.Fatalf("browspr.HandleAuthCreateAccountsRpc(%v) failed: %v", message2, err)
	}

	// Verify that HandleAuthGetAccountsRpc returns the new account.
	gotAccounts2, err := browspr.HandleAuthGetAccountsRpc(nilValue)
	if err != nil {
		t.Fatalf("browspr.HandleAuthGetAccountsRpc(%v) failed: %v", nilValue, err)
	}
	if want := vdl.ValueOf([]string{account1.RawString(), account2.RawString()}); !vdl.EqualValue(want, gotAccounts2) {
		t.Fatalf("Expected account to be %v but got empty but got %v", want, gotAccounts2)
	}

	// Verify that principalManager has both accounts
	if b, err := browspr.principalManager.BlessingsForAccount(account1.RawString()); err != nil || b.IsZero() {
		t.Fatalf("Failed to get Blessings for account %v: got %v, %v", account1, b, err)
	}
	if b, err := browspr.principalManager.BlessingsForAccount(account2.RawString()); err != nil || b.IsZero() {
		t.Fatalf("Failed to get Blessings for account %v: got %v, %v", account2, b, err)
	}
}

func TestHandleAssocAccount(t *testing.T) {
	browspr, teardown := setup(t)
	defer teardown()

	// First create an account.
	account := "mock-account"
	principal := v23.GetPrincipal(browspr.ctx)
	blessing, err := principal.BlessSelf(account)
	if err != nil {
		t.Fatalf("browspr.rt.Principal.BlessSelf(%v) failed: %v", account, err)
	}
	if err := browspr.principalManager.AddAccount(account, blessing); err != nil {
		t.Fatalf("browspr.principalManager.AddAccount(%v, %v) failed; %v", account, blessing, err)
	}

	origin := "https://my.webapp.com:443"

	// Verify that HandleAuthOriginHasAccountRpc returns false
	hasAccountMessage := vdl.ValueOf(OriginHasAccountMessage{
		Origin: origin,
	})
	hasAccount, err := browspr.HandleAuthOriginHasAccountRpc(hasAccountMessage)
	if err != nil {
		t.Fatal(err)
	}
	if hasAccount.Bool() {
		t.Fatalf("Expected browspr.HandleAuthOriginHasAccountRpc(%v) to be false but was true", hasAccountMessage)
	}

	assocAccountMessage := vdl.ValueOf(AssociateAccountMessage{
		Account: account,
		Origin:  origin,
	})

	if _, err := browspr.HandleAuthAssociateAccountRpc(assocAccountMessage); err != nil {
		t.Fatalf("browspr.HandleAuthAssociateAccountRpc(%v) failed: %v", assocAccountMessage, err)
	}

	// Verify that HandleAuthOriginHasAccountRpc returns true
	hasAccount, err = browspr.HandleAuthOriginHasAccountRpc(hasAccountMessage)
	if err != nil {
		t.Fatal(err)
	}
	if !hasAccount.Bool() {
		t.Fatalf("Expected browspr.HandleAuthOriginHasAccountRpc(%v) to be true but was false", hasAccountMessage)
	}

	// Verify that principalManager has the correct principal for the origin
	got, err := browspr.principalManager.Principal(origin)
	if err != nil {
		t.Fatalf("browspr.principalManager.Principal(%v) failed: %v", origin, err)
	}

	if got == nil {
		t.Fatalf("Expected browspr.principalManager.Principal(%v) to return a valid principal, but got %v", origin, got)
	}
}

func TestHandleAssocAccountWithMissingAccount(t *testing.T) {
	browspr, teardown := setup(t)
	defer teardown()

	account := "mock-account"
	origin := "https://my.webapp.com:443"
	message := vdl.ValueOf(AssociateAccountMessage{
		Account: account,
		Origin:  origin,
	})

	if _, err := browspr.HandleAuthAssociateAccountRpc(message); err == nil {
		t.Fatalf("browspr.HandleAuthAssociateAccountRpc(%v) should have failed but did not.", message)
	}

	// Verify that principalManager creates no principal for the origin
	got, err := browspr.principalManager.Principal(origin)
	if err == nil {
		t.Fatalf("Expected browspr.principalManager.Principal(%v) to fail, but got: %v", origin, got)
	}

	if got != nil {
		t.Fatalf("Expected browspr.principalManager.Principal(%v) not to return a principal, but got %v", origin, got)
	}

	// Verify that HandleAuthOriginHasAccountRpc returns false
	hasAccountMessage := vdl.ValueOf(OriginHasAccountMessage{
		Origin: origin,
	})
	hasAccount, err := browspr.HandleAuthOriginHasAccountRpc(hasAccountMessage)
	if err != nil {
		t.Fatal(err)
	}
	if hasAccount.Bool() {
		t.Fatalf("Expected browspr.HandleAuthOriginHasAccountRpc(%v) to be false but was true", hasAccountMessage)
	}
}
