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

import (
	"fmt"
	"reflect"
	"testing"
	"time"

	"v.io/v23/context"
	"v.io/v23/uniqueid"
	"v.io/v23/vdl"
	"v.io/v23/verror"
)

func TestStandardCaveatFactories(t *testing.T) {
	var (
		self      = newPrincipal(t)
		balice, _ = UnionOfBlessings(blessSelf(t, self, "alice:phone"), blessSelf(t, self, "alice:tablet"))
		bother    = blessSelf(t, self, "other")
		b, _      = UnionOfBlessings(balice, bother)
		now       = time.Now()
		call      = NewCall(&CallParams{
			Timestamp:      now,
			Method:         "Foo",
			LocalPrincipal: self,
			LocalBlessings: b,
		})
		C     = newCaveat
		tests = []struct {
			cav Caveat
			ok  bool
		}{
			// ExpiryCaveat
			{C(NewExpiryCaveat(now.Add(time.Second))), true},
			{C(NewExpiryCaveat(now.Add(-1 * time.Second))), false},
			// MethodCaveat
			{C(NewMethodCaveat("Foo")), true},
			{C(NewMethodCaveat("Bar")), false},
			{C(NewMethodCaveat("Foo", "Bar")), true},
			{C(NewMethodCaveat("Bar", "Baz")), false},
			// PeerBlesingsCaveat
			{C(NewCaveat(PeerBlessingsCaveat, []BlessingPattern{"alice:phone"})), true},
			{C(NewCaveat(PeerBlessingsCaveat, []BlessingPattern{"alice:tablet", "other"})), true},
			{C(NewCaveat(PeerBlessingsCaveat, []BlessingPattern{"alice:laptop", "other", "alice:$"})), false},
			{C(NewCaveat(PeerBlessingsCaveat, []BlessingPattern{"alice:laptop", "other", "alice"})), true},
		}
	)

	AddToRoots(self, balice)

	ctx, cancel := context.RootContext()
	defer cancel()
	for idx, test := range tests {
		err := test.cav.Validate(ctx, call)
		if test.ok && err != nil {
			t.Errorf("#%d: %v.Validate(...) failed validation: %v", idx, test.cav, err)
		} else if !test.ok && verror.ErrorID(err) != ErrCaveatValidation.ID {
			t.Errorf("#%d: %v.Validate(...) returned error='%v' (errorid=%v), want errorid=%v", idx, test.cav, err, verror.ErrorID(err), ErrCaveatValidation.ID)
		}
	}
}

func TestPublicKeyThirdPartyCaveat(t *testing.T) {
	var (
		now          = time.Now()
		valid        = newCaveat(NewExpiryCaveat(now.Add(time.Second)))
		expired      = newCaveat(NewExpiryCaveat(now.Add(-1 * time.Second)))
		discharger   = newPrincipal(t)
		randomserver = newPrincipal(t)
		ctxAndCall   = func(method string, discharges ...Discharge) (*context.T, Call) {
			params := &CallParams{
				Timestamp:        now,
				Method:           method,
				RemoteDischarges: make(map[string]Discharge),
			}
			for _, d := range discharges {
				params.RemoteDischarges[d.ID()] = d
			}
			root, _ := context.RootContext()
			return root, NewCall(params)
		}
	)

	tpc, err := NewPublicKeyCaveat(discharger.PublicKey(), "location", ThirdPartyRequirements{}, valid)
	if err != nil {
		t.Fatal(err)
	}
	// Caveat should fail validation without a discharge
	if err := matchesError(tpc.Validate(ctxAndCall("Method1")), "missing discharge"); err != nil {
		t.Fatal(err)
	}
	// Should validate when the discharge is present (and caveats on the discharge are met).
	d, err := discharger.MintDischarge(tpc, newCaveat(NewMethodCaveat("Method1")))
	if err != nil {
		t.Fatal(err)
	}
	if err := tpc.Validate(ctxAndCall("Method1", d)); err != nil {
		t.Fatal(err)
	}
	// Should fail validation when caveats on the discharge are not met.
	if err := matchesError(tpc.Validate(ctxAndCall("Method2", d)), "discharge failed to validate"); err != nil {
		t.Fatal(err)
	}
	// Discharge can be converted to and from wire format:
	var d2 Discharge
	if err := roundTrip(d, &d2); err != nil || !reflect.DeepEqual(d, d2) {
		t.Errorf("Got (%#v, %v), want (%#v, nil)", d2, err, d)
	}
	// A discharge minted by another principal should not be respected.
	if d, err = randomserver.MintDischarge(tpc, UnconstrainedUse()); err == nil {
		if err := matchesError(tpc.Validate(ctxAndCall("Method1", d)), "signature verification on discharge"); err != nil {
			t.Fatal(err)
		}
	}
	// And ThirdPartyCaveat should not be dischargeable if caveats encoded within it fail validation.
	tpc, err = NewPublicKeyCaveat(discharger.PublicKey(), "location", ThirdPartyRequirements{}, expired)
	if err != nil {
		t.Fatal(err)
	}
	ctx, cancel := context.RootContext()
	defer cancel()
	call := NewCall(&CallParams{Timestamp: now})
	if merr := matchesError(tpc.ThirdPartyDetails().Dischargeable(ctx, call), "could not validate embedded restriction"); merr != nil {
		t.Fatal(merr)
	}
}

func TestCaveat(t *testing.T) {
	uid, err := uniqueid.Random()
	if err != nil {
		t.Fatal(err)
	}
	anyCd := CaveatDescriptor{
		Id:        uid,
		ParamType: vdl.AnyType,
	}
	if _, err := NewCaveat(anyCd, 9); verror.ErrorID(err) != ErrCaveatParamAny.ID {
		t.Errorf("Got '%v' (errorid=%v), want errorid=%v", err, verror.ErrorID(err), ErrCaveatParamAny.ID)
	}
	cd := CaveatDescriptor{
		Id:        uid,
		ParamType: vdl.TypeOf(string("")),
	}
	if _, err := NewCaveat(cd, nil); verror.ErrorID(err) != ErrCaveatParamTypeMismatch.ID {
		t.Errorf("Got '%v' (errorid=%v), want errorid=%v", err, verror.ErrorID(err), ErrCaveatParamTypeMismatch.ID)
	}
	// A param of type *vdl.Value with underlying type string should succeed.
	if _, err := NewCaveat(cd, vdl.StringValue("")); err != nil {
		t.Errorf("vdl value should have succeeded: %v", err)
	}
	call := NewCall(&CallParams{
		Method: "Foo",
	})
	ctx, cancel := context.RootContext()
	defer cancel()
	c1, err := NewCaveat(cd, "Foo")
	if err != nil {
		t.Fatal(err)
	}
	c2, err := NewCaveat(cd, "Bar")
	if err != nil {
		t.Fatal(err)
	}
	// Validation will fail when the validation function isn't registered.
	if err := c1.Validate(ctx, call); verror.ErrorID(err) != ErrCaveatNotRegistered.ID {
		t.Errorf("Got '%v' (errorid=%v), want errorid=%v", err, verror.ErrorID(err), ErrCaveatNotRegistered.ID)
	}
	// Once registered, then it should be invoked
	RegisterCaveatValidator(cd, func(ctx *context.T, call Call, param string) error {
		if call.Method() == param {
			return nil
		}
		return fmt.Errorf("na na na")
	})
	if err := c1.Validate(ctx, call); err != nil {
		t.Error(err)
	}
	if err := c2.Validate(ctx, call); verror.ErrorID(err) != ErrCaveatValidation.ID {
		t.Errorf("Got '%v' (errorid=%v), want errorid=%v", err, verror.ErrorID(err), ErrCaveatValidation.ID)
	}
	// If a malformed caveat was received, then validation should fail
	c3 := Caveat{Id: cd.Id, ParamVom: nil}
	if err := c3.Validate(ctx, call); verror.ErrorID(err) != ErrCaveatParamCoding.ID {
		t.Errorf("Got '%v' (errorid=%v), want errorid=%v", err, verror.ErrorID(err), ErrCaveatParamCoding.ID)
	}
}

func TestRegisterCaveat(t *testing.T) {
	uid, err := uniqueid.Random()
	if err != nil {
		t.Fatal(err)
	}
	var (
		cd = CaveatDescriptor{
			Id:        uid,
			ParamType: vdl.TypeOf(string("")),
		}
		npanics     int
		expectPanic = func(details string) {
			npanics++
			if err := recover(); err == nil {
				t.Errorf("%s: expected a panic", details)
			}
		}
	)
	func() {
		defer expectPanic("not a function")
		RegisterCaveatValidator(cd, "not a function")
	}()
	func() {
		defer expectPanic("wrong #outputs")
		RegisterCaveatValidator(cd, func(*context.T, Call, string) (error, error) { return nil, nil })
	}()
	func() {
		defer expectPanic("bad output type")
		RegisterCaveatValidator(cd, func(*context.T, Call, string) int { return 0 })
	}()
	func() {
		defer expectPanic("wrong #inputs")
		RegisterCaveatValidator(cd, func(*context.T, string) error { return nil })
	}()
	func() {
		defer expectPanic("bad input arg 0")
		RegisterCaveatValidator(cd, func(int, Call, string) error { return nil })
	}()
	func() {
		defer expectPanic("bad input arg 1")
		RegisterCaveatValidator(cd, func(*context.T, int, string) error { return nil })
	}()
	func() {
		defer expectPanic("bad input arg 2")
		RegisterCaveatValidator(cd, func(*context.T, Call, int) error { return nil })
	}()
	func() {
		// Successful registration: No panic:
		RegisterCaveatValidator(cd, func(*context.T, Call, string) error { return nil })
	}()
	func() {
		defer expectPanic("Duplication registration")
		RegisterCaveatValidator(cd, func(*context.T, Call, string) error { return nil })
	}()
	if got, want := npanics, 8; got != want {
		t.Errorf("Got %d panics, want %d", got, want)
	}
}

func TestThirdPartyDetails(t *testing.T) {
	niltests := []Caveat{
		newCaveat(NewExpiryCaveat(time.Now())),
		newCaveat(NewMethodCaveat("Foo", "Bar")),
	}
	for _, c := range niltests {
		if tp := c.ThirdPartyDetails(); tp != nil {
			t.Errorf("Caveat [%v] recognized as a third-party caveat: %v", c, tp)
		}
	}
	req := ThirdPartyRequirements{ReportMethod: true}
	c, err := NewPublicKeyCaveat(newPrincipal(t).PublicKey(), "location", req, newCaveat(NewExpiryCaveat(time.Now())))
	if err != nil {
		t.Fatal(err)
	}
	if got := c.ThirdPartyDetails(); got.Location() != "location" {
		t.Errorf("Got location %q, want %q", got.Location(), "location")
	} else if !reflect.DeepEqual(got.Requirements(), req) {
		t.Errorf("Got requirements %+v, want %+v", got.Requirements(), req)
	}
}

func TestPublicKeyDischargeExpiry(t *testing.T) {
	var (
		discharger = newPrincipal(t)
		now        = time.Now()
		oneh       = newCaveat(NewExpiryCaveat(now.Add(time.Hour)))
		twoh       = newCaveat(NewExpiryCaveat(now.Add(2 * time.Hour)))
		threeh     = newCaveat(NewExpiryCaveat(now.Add(3 * time.Hour)))
	)

	tpc, err := NewPublicKeyCaveat(discharger.PublicKey(), "location", ThirdPartyRequirements{}, oneh)
	if err != nil {
		t.Fatal(err)
	}

	// Mint three discharges; one with no ExpiryCaveat...
	noExpiry, err := discharger.MintDischarge(tpc, newCaveat(NewMethodCaveat("Method1")))
	if err != nil {
		t.Fatal(err)
	}
	// another with an ExpiryCaveat one hour from now...
	oneCav, err := discharger.MintDischarge(tpc, oneh)
	if err != nil {
		t.Fatal(err)
	}
	// and finally, one with an ExpiryCaveat of one, two, and three hours from now.
	// Use a random order to help test that Expiry always returns the earliest time.
	threeCav, err := discharger.MintDischarge(tpc, threeh, oneh, twoh)
	if err != nil {
		t.Fatal(err)
	}

	if exp := noExpiry.Expiry(); !exp.IsZero() {
		t.Errorf("got %v, want %v", exp, time.Time{})
	}
	if got, want := oneCav.Expiry().UTC(), now.Add(time.Hour).UTC(); got != want {
		t.Errorf("got %v, want %v", got, want)
	}
	if got, want := threeCav.Expiry().UTC(), now.Add(time.Hour).UTC(); got != want {
		t.Errorf("got %v, want %v", got, want)
	}
}

// Benchmark creation of a new caveat using one of the simplest caveats
// (expiry)
func BenchmarkNewCaveat(b *testing.B) {
	for i := 0; i < b.N; i++ {
		if _, err := NewExpiryCaveat(time.Time{}); err != nil {
			b.Fatal(err)
		}
	}
}

// Benchmark caveat valdation using one of the simplest caveats (expiry).
func BenchmarkValidateCaveat(b *testing.B) {
	cav, err := NewExpiryCaveat(time.Now())
	if err != nil {
		b.Fatal(err)
	}
	call := NewCall(&CallParams{})
	ctx, cancel := context.RootContext()
	defer cancel()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		cav.Validate(ctx, call)
	}
}
