// 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 signing_test implements a test for the package
// v.io/syncbase/x/ref/services/syncbase/signing
package signing_test

import "crypto/sha256"
import "testing"
import "time"

import "v.io/syncbase/x/ref/services/syncbase/signing"
import "v.io/syncbase/x/ref/services/syncbase/signing/krl"
import "v.io/v23/naming"
import "v.io/v23/security"
import "v.io/v23/vdl"
import "v.io/v23/vom"
import "v.io/v23/verror"
import "v.io/x/ref/test"
import lib_security "v.io/x/ref/lib/security"

import _ "v.io/x/ref/runtime/factories/generic"

// --------------------------------------
// The following implements a fake security.Call.
type fakeCall struct {
	localPrincipal  security.Principal
	localBlessings  security.Blessings
	remoteBlessings security.Blessings
}

func (fc *fakeCall) Timestamp() time.Time                            { return time.Now() }
func (fc *fakeCall) Method() string                                  { return "the_method_name" }
func (fc *fakeCall) MethodTags() []*vdl.Value                        { return nil }
func (fc *fakeCall) Suffix() string                                  { return "the_suffix" }
func (fc *fakeCall) LocalDischarges() map[string]security.Discharge  { return nil }
func (fc *fakeCall) RemoteDischarges() map[string]security.Discharge { return nil }
func (fc *fakeCall) LocalPrincipal() security.Principal              { return fc.localPrincipal }
func (fc *fakeCall) LocalBlessings() security.Blessings              { return fc.localBlessings }
func (fc *fakeCall) RemoteBlessings() security.Blessings             { return fc.remoteBlessings }
func (fc *fakeCall) LocalEndpoint() naming.Endpoint                  { return nil }
func (fc *fakeCall) RemoteEndpoint() naming.Endpoint                 { return nil }

// --------------------------------------

// A principalDesc holds the local state of a single principal in the tests below.
type principalDesc struct {
	name                string
	principal           security.Principal
	blessings           security.Blessings
	krl                 *krl.KRL
	authorBlessingsData *signing.BlessingsData
	names               []string
	marshalledBlessings []byte
	blessingsHash       []byte
	validatorData       *signing.ValidatorData
	validatorHash       []byte
	cache               *signing.ValidationCache
	data                *signing.DataWithSignature
}

// makePrincipal() returns a pointer to a newly-initialized principalDesc,
// with a unique key, and a single blessing named with its own name.
func makePrincipal(t testing.TB, name string) (desc *principalDesc) {
	var err error
	desc = new(principalDesc)
	desc.name = name
	desc.principal, err = lib_security.NewPrincipal()
	if err != nil {
		t.Fatalf("security.CreatePrincipal %q failed: %v", desc.name, err)
	}
	desc.blessings, err = desc.principal.BlessSelf(desc.name)
	if err != nil {
		t.Fatalf("principal.BlessSelf %q failed: %v", desc.name, err)
	}
	desc.krl = krl.New()
	desc.cache = signing.NewValidationCache(5 * time.Second)
	return desc
}

// makePrincipals() creares one principal per name, and adds
// the blessings of each to the roots of all.
func makePrincipals(t testing.TB, names ...string) (principals []*principalDesc) {
	for i := range names {
		principals = append(principals, makePrincipal(t, names[i]))
	}
	for i := range principals {
		for j := range principals {
			principals[j].principal.AddToRoots(principals[i].blessings)
		}
	}
	return principals
}

// BenchmarkHashData() measures the time taken to do a cryptogrqaphic hash of
// 1kBytes.
func BenchmarkHashData(b *testing.B) {
	var block [1024]byte
	hasher := sha256.New()
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		hasher.Write(block[:])
	}
}

// BenchmarkSignData() measures the time taken to sign something with
// signing.SignData().
func BenchmarkSignData(b *testing.B) {
	ctx, shutdown := test.V23Init()
	defer shutdown()
	var err error
	author := makePrincipal(b, "author")
	dataToSign := []signing.Item{signing.ItemData{Value: []byte("hello")}}
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		author.data, author.authorBlessingsData, err =
			signing.SignData(ctx, author.cache, author.principal, author.blessings, dataToSign)
	}
	if err != nil {
		panic(err)
	}
}

// BenchmarkSign1000Data() measures the time taken to sign 1000 small data
// items with signing.SignData().
func BenchmarkSign1000Data(b *testing.B) {
	ctx, shutdown := test.V23Init()
	defer shutdown()
	var err error
	author := makePrincipal(b, "author")
	var dataToSign []signing.Item
	for i := 0; i != 1000; i++ {
		dataToSign = append(dataToSign, signing.ItemData{Value: []byte("hello")})
	}
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		author.data, author.authorBlessingsData, err =
			signing.SignData(ctx, author.cache, author.principal, author.blessings, dataToSign)
	}
	if err != nil {
		panic(err)
	}
}

// BenchmarkSignData() measures the time taken to check a validated signature
// with DataWithSignature.Check().
func BenchmarkCheckData(b *testing.B) {
	ctx, shutdown := test.V23Init()
	defer shutdown()
	var err error

	principals := makePrincipals(b, "author", "validator", "checker")
	author := principals[0]
	validator := principals[1]
	checker := principals[2]

	dataToSign := []signing.Item{signing.ItemData{Value: []byte("hello")}}
	author.data, author.authorBlessingsData, err =
		signing.SignData(ctx, author.cache, author.principal, author.blessings, dataToSign)
	if err != nil {
		panic(err)
	}
	callToValidator := fakeCall{
		localPrincipal:  validator.principal,
		localBlessings:  validator.blessings,
		remoteBlessings: author.blessings,
	}
	validator.names, err = author.data.Check(ctx, author.cache, &callToValidator, validator.krl, 24*30*time.Hour)
	if err != nil {
		panic(err)
	}
	callToChecker := fakeCall{
		localPrincipal:  checker.principal,
		localBlessings:  checker.blessings,
		remoteBlessings: validator.blessings,
	}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		checker.names, err = author.data.Check(ctx, author.cache, &callToChecker, checker.krl, 24*30*time.Hour)
	}
}

// BenchmarkSign1000Data() measures the time taken to check a validated
// signature over 1000 small data items with DataWithSignature.Check().
func BenchmarkCheck1000Data(b *testing.B) {
	ctx, shutdown := test.V23Init()
	defer shutdown()
	var err error

	principals := makePrincipals(b, "author", "validator", "checker")
	author := principals[0]
	validator := principals[1]
	checker := principals[2]

	var dataToSign []signing.Item
	for i := 0; i != 1000; i++ {
		dataToSign = append(dataToSign, signing.ItemData{Value: []byte("hello")})
	}
	author.data, author.authorBlessingsData, err =
		signing.SignData(ctx, author.cache, author.principal, author.blessings, dataToSign)
	if err != nil {
		panic(err)
	}
	callToValidator := fakeCall{
		localPrincipal:  validator.principal,
		localBlessings:  validator.blessings,
		remoteBlessings: author.blessings,
	}
	validator.names, err = author.data.Check(ctx, author.cache, &callToValidator, validator.krl, 24*30*time.Hour)
	if err != nil {
		panic(err)
	}
	callToChecker := fakeCall{
		localPrincipal:  checker.principal,
		localBlessings:  checker.blessings,
		remoteBlessings: validator.blessings,
	}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		checker.names, err = author.data.Check(ctx, author.cache, &callToChecker, checker.krl, 24*30*time.Hour)
	}
}

// BenchmarkMarshallBlessings() measures the time taken to marshal a Blessings.
func BenchmarkMarshallBlessings(b *testing.B) {
	var err error
	author := makePrincipal(b, "author")
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		author.marshalledBlessings, err = vom.Encode(author.blessings)
	}
	if err != nil {
		b.Fatalf("vom.Encode failed: %v", err)
	}
}

// BenchmarkUnmarshallBlessings() measures the time taken to unmashal a Blessings.
func BenchmarkUnmarshallBlessings(b *testing.B) {
	var err error
	author := makePrincipal(b, "author")
	author.marshalledBlessings, err = vom.Encode(author.blessings)
	if err != nil {
		b.Fatalf("vom.Encode failed: %v", err)
	}
	var blessings security.Blessings
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		err = vom.Decode(author.marshalledBlessings, &blessings)
	}
	if err != nil {
		b.Fatalf("vom.Encode failed: %v", err)
	}
}

// BenchmarkMarshallPublicKey() measures the time taken to marshal a PublicKey.
func BenchmarkMarshallPublicKey(b *testing.B) {
	var err error
	author := makePrincipal(b, "author")
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_, err = author.principal.PublicKey().MarshalBinary()
	}
	if err != nil {
		b.Fatalf("MarshalBinary() failed: %v", err)
	}
}

// BenchmarkUnmarshallPublicKey() measures the time taken to unmarshal a PublicKey.
func BenchmarkUnmarshallPublicKey(b *testing.B) {
	var err error
	author := makePrincipal(b, "author")
	var marshalledKey []byte
	marshalledKey, err = author.principal.PublicKey().MarshalBinary()
	if err != nil {
		b.Fatalf("MarshalBinary() failed: %v", err)
	}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_, err = security.UnmarshalPublicKey(marshalledKey)
	}
	if err != nil {
		b.Fatalf("MarshalBinary() failed: %v", err)
	}
}

// TestSignData() tests that a complete flow of signing, validating, and
// checking works on a DataWithSignature.
func TestSignData(t *testing.T) {
	ctx, shutdown := test.V23Init()
	defer shutdown()

	var err error

	principals := makePrincipals(t, "author", "validator", "checker")
	author := principals[0]
	validator := principals[1]
	checker := principals[2]

	// Add each princpipal's blessings to each principal's roots.
	pdList := []*principalDesc{author, validator, checker}
	for i := 0; i != len(pdList); i++ {
		for j := 0; j != len(pdList); j++ {
			pdList[j].principal.AddToRoots(pdList[i].blessings)
		}
	}

	// --------------------------------------
	// Author
	// Sign some data.
	dataToSign := []signing.Item{
		signing.ItemData{Value: []byte("hello")},
		signing.ItemData{Value: []byte("world")},
		signing.ItemData{Value: []byte("!")},
	}
	author.data, author.authorBlessingsData, err =
		signing.SignData(ctx, author.cache, author.principal, author.blessings, dataToSign)
	if err != nil {
		t.Fatalf("signing.SignData failed: %v", err)
	}
	if author.data.IsValidated {
		t.Fatalf("signing.SignData generated data with IsValidated set")
	}

	// --------------------------------------
	// Validator
	callToValidator := fakeCall{
		localPrincipal:  validator.principal,
		localBlessings:  validator.blessings,
		remoteBlessings: author.blessings,
	}
	// The validator receives author.data from the author.
	validator.data = new(signing.DataWithSignature)
	*validator.data = *author.data
	// Initially the validator doesn't have the author BlessingsData.
	validator.authorBlessingsData = validator.cache.LookupBlessingsData(ctx, validator.data.BlessingsHash)
	if validator.authorBlessingsData != nil {
		t.Errorf("found non-nil BlessingsData for validator.data.BlessingsHash in validator's ValidationCache")
	}
	validator.names, err = validator.data.Check(ctx, validator.cache, &callToValidator, validator.krl, 24*30*time.Hour)
	if verror.ErrorID(err) != signing.ErrNeedAuthorBlessingsForHash.ID {
		t.Fatalf("validator.data.Check got err %v, want %s", err, signing.ErrNeedAuthorBlessingsForHash.ID)
	}

	// The validator receives the author's marshalled blessings from the author.
	validator.marshalledBlessings = author.authorBlessingsData.MarshalledBlessings
	validator.blessingsHash, validator.authorBlessingsData, err = validator.cache.AddWireBlessings(ctx, validator.marshalledBlessings)
	if err != nil {
		t.Fatalf("validator can't add author's marshalled belssings to its ValidationCache: %v", err)
	}

	validator.names, err = validator.data.Check(ctx, validator.cache, &callToValidator, validator.krl, 24*30*time.Hour)
	if err != nil {
		t.Fatalf("validator error calling Check() on data: %v", err)
	}
	if !validator.data.IsValidated {
		t.Fatalf("signing.Check didn't set IsValidated")
	}
	// Validator's cache should now have the author's BlessingData, and the validator's ValidatorData.
	validator.authorBlessingsData = validator.cache.LookupBlessingsData(ctx, validator.data.BlessingsHash)
	if validator.authorBlessingsData == nil {
		t.Errorf("didn't finf BlessingsData for validator.data.BlessingsHash in validator's ValidationCache")
	}
	validator.validatorData = validator.cache.LookupValidatorData(ctx, validator.data.ValidatorDataHash)

	// --------------------------------------
	// Checker
	callToChecker := fakeCall{
		localPrincipal:  checker.principal,
		localBlessings:  checker.blessings,
		remoteBlessings: validator.blessings,
	}
	// The checker recieves validator.data from the validator, except that
	// data item 1 is replaced by its hash, because (for example) the
	// check is not allowed to see it.
	checker.data = new(signing.DataWithSignature)
	*checker.data = *validator.data
	checker.data.Data[1] = signing.ItemHash{Value: signing.SumByteVectorWithLength(checker.data.Data[1].(signing.ItemData).Value)}

	// Initially the checker doesn't have the author BlessingsData, or the validator ValidatorData.
	checker.authorBlessingsData = checker.cache.LookupBlessingsData(ctx, checker.data.BlessingsHash)
	if checker.authorBlessingsData != nil {
		t.Errorf("found non-nil blessings data for checker.data.BlessingsHash hash in checker's ValidationCache")
	}
	checker.names, err = checker.data.Check(ctx, checker.cache, &callToChecker, checker.krl, 24*30*time.Hour)
	if verror.ErrorID(err) != signing.ErrNeedAuthorBlessingsAndValidatorDataForHash.ID {
		t.Fatalf("checker.data.Check got err %v, want %s", err, signing.ErrNeedAuthorBlessingsAndValidatorDataForHash.ID)
	}

	// The checker receives the author's marshalled blessings from the validator.
	checker.marshalledBlessings = validator.marshalledBlessings
	checker.blessingsHash, checker.authorBlessingsData, err = checker.cache.AddWireBlessings(ctx, checker.marshalledBlessings)
	if err != nil {
		t.Fatalf("checker can't add author's marshalled belssings to its ValidationCache: %v", err)
	}
	checker.names, err = checker.data.Check(ctx, checker.cache, &callToChecker, checker.krl, 24*30*time.Hour)
	if verror.ErrorID(err) != signing.ErrNeedValidatorDataForHash.ID {
		t.Fatalf("checker.data.Check got err %v, want %s", err, signing.ErrNeedValidatorDataForHash.ID)
	}

	// The checker receives the validator's data from the validator, passing through the wire format.
	wvd := signing.ToWireValidatorData(validator.validatorData)
	var vd signing.ValidatorData
	vd, err = signing.FromWireValidatorData(&wvd)
	if err != nil {
		t.Fatalf("signing.FromWireValidatorData got error:  %v", err)
	}
	checker.validatorData = &vd

	// The checker adds the ValidatorData to its cache.
	checker.validatorHash = checker.cache.AddValidatorData(ctx, checker.validatorData)

	// And now the Check() operation should work.
	checker.names, err = checker.data.Check(ctx, checker.cache, &callToChecker, checker.krl, 24*30*time.Hour)
	if err != nil {
		t.Fatalf("checker.data.Check got unexpected err %v", err)
	}
}
