package app

import (
	"bytes"
	"encoding/json"
	"fmt"
	"reflect"
	"strings"
	"sync"
	"testing"
	"time"
	"veyron.io/veyron/veyron/services/wsprd/lib"
	"veyron.io/veyron/veyron/services/wsprd/signature"
	"veyron.io/veyron/veyron2"
	"veyron.io/veyron/veyron2/ipc"
	"veyron.io/veyron/veyron2/naming"
	"veyron.io/veyron/veyron2/rt"
	"veyron.io/veyron/veyron2/security"
	"veyron.io/veyron/veyron2/vdl/vdlutil"
	"veyron.io/veyron/veyron2/verror"
	"veyron.io/veyron/veyron2/vlog"
	"veyron.io/veyron/veyron2/vom"
	vom_wiretype "veyron.io/veyron/veyron2/vom/wiretype"
	"veyron.io/veyron/veyron2/wiretype"

	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/proxy"
	mounttable "veyron.io/veyron/veyron/services/mounttable/lib"
)

var (
	ctxFooAlice = makeMockSecurityContext("Foo", "test/alice")
	ctxBarAlice = makeMockSecurityContext("Bar", "test/alice")
	ctxFooBob   = makeMockSecurityContext("Foo", "test/bob")
	ctxBarBob   = makeMockSecurityContext("Bar", "test/bob")
)
var r = rt.Init()

type simpleAdder struct{}

func (s simpleAdder) Add(_ ipc.ServerCall, a, b int32) (int32, error) {
	return a + b, nil
}

func (s simpleAdder) Divide(_ ipc.ServerCall, a, b int32) (int32, error) {
	if b == 0 {
		return 0, verror.BadArgf("can't divide by zero")
	}
	return a / b, nil
}

func (s simpleAdder) StreamingAdd(call ipc.ServerCall) (int32, error) {
	total := int32(0)
	var value int32
	for err := call.Recv(&value); err == nil; err = call.Recv(&value) {
		total += value
		call.Send(total)
	}
	return total, nil
}

func (s simpleAdder) Signature(call ipc.ServerCall) (ipc.ServiceSignature, error) {
	result := ipc.ServiceSignature{Methods: make(map[string]ipc.MethodSignature)}
	result.Methods["Add"] = ipc.MethodSignature{
		InArgs: []ipc.MethodArgument{
			{Name: "A", Type: 36},
			{Name: "B", Type: 36},
		},
		OutArgs: []ipc.MethodArgument{
			{Name: "Value", Type: 36},
			{Name: "Err", Type: 65},
		},
	}

	result.Methods["Divide"] = ipc.MethodSignature{
		InArgs: []ipc.MethodArgument{
			{Name: "A", Type: 36},
			{Name: "B", Type: 36},
		},
		OutArgs: []ipc.MethodArgument{
			{Name: "Value", Type: 36},
			{Name: "Err", Type: 65},
		},
	}

	result.Methods["StreamingAdd"] = ipc.MethodSignature{
		InArgs: []ipc.MethodArgument{},
		OutArgs: []ipc.MethodArgument{
			{Name: "Value", Type: 36},
			{Name: "Err", Type: 65},
		},
		InStream:  36,
		OutStream: 36,
	}
	result.TypeDefs = []vdlutil.Any{
		wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}

	return result, nil
}

func startAnyServer(servesMT bool, dispatcher ipc.Dispatcher) (ipc.Server, naming.Endpoint, error) {
	// Create a new server instance.
	s, err := r.NewServer(veyron2.ServesMountTableOpt(servesMT))
	if err != nil {
		return nil, nil, err
	}

	endpoint, err := s.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		return nil, nil, err
	}

	if err := s.Serve("", dispatcher); err != nil {
		return nil, nil, err
	}
	return s, endpoint, nil
}

func startAdderServer() (ipc.Server, naming.Endpoint, error) {
	return startAnyServer(false, ipc.LeafDispatcher(simpleAdder{}, nil))
}

func startProxy() (*proxy.Proxy, error) {
	rid, err := naming.NewRoutingID()
	if err != nil {
		return nil, err
	}
	return proxy.New(rid, nil, "tcp", "127.0.0.1:0", "")
}

func startMountTableServer() (ipc.Server, naming.Endpoint, error) {
	mt, err := mounttable.NewMountTable("")
	if err != nil {
		return nil, nil, err
	}
	return startAnyServer(true, mt)
}

type response struct {
	Type    lib.ResponseType
	Message interface{}
}

type testWriter struct {
	sync.Mutex
	stream []response
	err    error
	logger vlog.Logger
	// If this channel is set then a message will be sent
	// to this channel after recieving a call to FinishMessage()
	notifier chan bool
}

func (w *testWriter) Send(responseType lib.ResponseType, msg interface{}) error {
	w.Lock()
	defer w.Unlock()
	// We serialize and deserialize the reponse so that we can do deep equal with
	// messages that contain non-exported structs.
	var buf bytes.Buffer
	if err := json.NewEncoder(&buf).Encode(response{Type: responseType, Message: msg}); err != nil {
		return err
	}

	var r response

	if err := json.NewDecoder(&buf).Decode(&r); err != nil {
		return err
	}

	w.stream = append(w.stream, r)
	if w.notifier != nil {
		w.notifier <- true
	}
	return nil

}

func (w *testWriter) Error(err error) {
	w.err = err
}

func (w *testWriter) streamLength() int {
	w.Lock()
	defer w.Unlock()
	return len(w.stream)
}

// Waits until there is at least n messages in w.stream. Returns an error if we timeout
// waiting for the given number of messages.
func (w *testWriter) waitForMessage(n int) error {
	if w.streamLength() >= n {
		return nil
	}
	w.Lock()
	w.notifier = make(chan bool, 1)
	w.Unlock()
	for w.streamLength() < n {
		select {
		case <-w.notifier:
			continue
		case <-time.After(time.Second):
			return fmt.Errorf("timed out")
		}
	}
	w.Lock()
	w.notifier = nil
	w.Unlock()
	return nil
}

func checkResponses(w *testWriter, expectedStream []response, err error, t *testing.T) {
	if !reflect.DeepEqual(expectedStream, w.stream) {
		t.Errorf("streams don't match: expected %v, got %v", expectedStream, w.stream)
	}

	if !reflect.DeepEqual(err, w.err) {
		t.Errorf("unexpected error, got: %v, expected: %v", err, w.err)
	}
}

var adderServiceSignature signature.JSONServiceSignature = signature.JSONServiceSignature{
	"add": signature.JSONMethodSignature{
		InArgs:      []string{"A", "B"},
		NumOutArgs:  2,
		IsStreaming: false,
	},
	"divide": signature.JSONMethodSignature{
		InArgs:      []string{"A", "B"},
		NumOutArgs:  2,
		IsStreaming: false,
	},
	"streamingAdd": signature.JSONMethodSignature{
		InArgs:      []string{},
		NumOutArgs:  2,
		IsStreaming: true,
	},
}

func TestGetGoServerSignature(t *testing.T) {
	s, endpoint, err := startAdderServer()
	if err != nil {
		t.Errorf("unable to start server: %v", err)
		t.Fail()
		return
	}
	defer s.Stop()
	controller, err := NewController(nil, "mockVeyronProxyEP")

	if err != nil {
		t.Errorf("Failed to create controller: %v", err)
	}
	jsSig, err := controller.getSignature(r.NewContext(), "/"+endpoint.String())
	if err != nil {
		t.Errorf("Failed to get signature: %v", err)
	}

	if !reflect.DeepEqual(jsSig, adderServiceSignature) {
		t.Errorf("Unexpected signature, got :%v, expected: %v", jsSig, adderServiceSignature)
	}
}

type goServerTestCase struct {
	method             string
	inArgs             []json.RawMessage
	numOutArgs         int32
	streamingInputs    []string
	streamingInputType vom.Type
	expectedStream     []response
	expectedError      error
}

func runGoServerTestCase(t *testing.T, test goServerTestCase) {
	s, endpoint, err := startAdderServer()
	if err != nil {
		t.Errorf("unable to start server: %v", err)
		t.Fail()
		return
	}
	defer s.Stop()

	controller, err := NewController(nil, "mockVeyronProxyEP")

	if err != nil {
		t.Errorf("unable to create controller: %v", err)
		t.Fail()
		return
	}

	writer := testWriter{
		logger: controller.logger,
	}
	var stream *outstandingStream
	if len(test.streamingInputs) > 0 {
		stream = newStream()
		controller.outstandingStreams[0] = stream
		go func() {
			for _, value := range test.streamingInputs {
				controller.SendOnStream(0, value, &writer)
			}
			controller.CloseStream(0)
		}()
	}

	request := veyronTempRPC{
		Name:        "/" + endpoint.String(),
		Method:      test.method,
		InArgs:      test.inArgs,
		NumOutArgs:  test.numOutArgs,
		IsStreaming: stream != nil,
	}
	controller.sendVeyronRequest(r.NewContext(), 0, &request, &writer, stream)

	checkResponses(&writer, test.expectedStream, test.expectedError, t)
}

func TestCallingGoServer(t *testing.T) {
	runGoServerTestCase(t, goServerTestCase{
		method:     "Add",
		inArgs:     []json.RawMessage{json.RawMessage("2"), json.RawMessage("3")},
		numOutArgs: 2,
		expectedStream: []response{
			response{
				Message: []interface{}{5.0},
				Type:    lib.ResponseFinal,
			},
		},
	})
}

func TestCallingGoServerWithError(t *testing.T) {
	runGoServerTestCase(t, goServerTestCase{
		method:        "Divide",
		inArgs:        []json.RawMessage{json.RawMessage("1"), json.RawMessage("0")},
		numOutArgs:    2,
		expectedError: verror.BadArgf("can't divide by zero"),
	})
}

func TestCallingGoWithStreaming(t *testing.T) {
	runGoServerTestCase(t, goServerTestCase{
		method:             "StreamingAdd",
		inArgs:             []json.RawMessage{},
		streamingInputs:    []string{"1", "2", "3", "4"},
		streamingInputType: vom_wiretype.Type{ID: 36},
		numOutArgs:         2,
		expectedStream: []response{
			response{
				Message: 1.0,
				Type:    lib.ResponseStream,
			},
			response{
				Message: 3.0,
				Type:    lib.ResponseStream,
			},
			response{
				Message: 6.0,
				Type:    lib.ResponseStream,
			},
			response{
				Message: 10.0,
				Type:    lib.ResponseStream,
			},
			response{
				Message: nil,
				Type:    lib.ResponseStreamClose,
			},
			response{
				Message: []interface{}{10.0},
				Type:    lib.ResponseFinal,
			},
		},
	})
}

type runningTest struct {
	controller       *Controller
	writer           *testWriter
	mounttableServer ipc.Server
	proxyServer      *proxy.Proxy
}

func serveServer() (*runningTest, error) {
	mounttableServer, endpoint, err := startMountTableServer()

	if err != nil {
		return nil, fmt.Errorf("unable to start mounttable: %v", err)
	}

	proxyServer, err := startProxy()

	if err != nil {
		return nil, fmt.Errorf("unable to start proxy: %v", err)
	}

	proxyEndpoint := proxyServer.Endpoint().String()

	writer := testWriter{}

	writerCreator := func(int64) lib.ClientWriter {
		return &writer
	}
	controller, err := NewController(writerCreator, "/"+proxyEndpoint,
		veyron2.NamespaceRoots{"/" + endpoint.String()})
	if err != nil {
		return nil, err
	}

	writer.logger = controller.logger

	controller.serve(serveRequest{
		Name:    "adder",
		Service: adderServiceSignature,
	}, &writer)

	return &runningTest{
		controller, &writer, mounttableServer, proxyServer,
	}, nil
}

func TestJavascriptServeServer(t *testing.T) {
	rt, err := serveServer()
	defer rt.mounttableServer.Stop()
	defer rt.proxyServer.Shutdown()
	defer rt.controller.Cleanup()
	if err != nil {
		t.Fatalf("could not serve server %v", err)
	}

	if len(rt.writer.stream) != 1 {
		t.Errorf("expected only one response, got %d", len(rt.writer.stream))
		return
	}

	resp := rt.writer.stream[0]

	if resp.Type != lib.ResponseFinal {
		t.Errorf("unknown stream message Got: %v, expected: serve response", resp)
		return
	}

	if msg, ok := resp.Message.(string); ok {
		if _, err := r.NewEndpoint(msg); err == nil {
			return
		}
	}
	t.Errorf("invalid endpdoint returned from serve: %v", resp.Message)
}

func TestJavascriptStopServer(t *testing.T) {
	rt, err := serveServer()
	defer rt.mounttableServer.Stop()
	defer rt.proxyServer.Shutdown()
	defer rt.controller.Cleanup()

	if err != nil {
		t.Errorf("could not serve server %v", err)
		return
	}

	// ensure there is only one server and then stop the server
	if len(rt.controller.servers) != 1 {
		t.Errorf("expected only one server but got: %d", len(rt.controller.servers))
		return
	}
	for serverId := range rt.controller.servers {
		rt.controller.removeServer(serverId)
	}

	// ensure there is no more servers now
	if len(rt.controller.servers) != 0 {
		t.Errorf("expected no server after stopping the only one but got: %d", len(rt.controller.servers))
		return
	}

	return
}

type jsServerTestCase struct {
	method string
	inArgs []interface{}
	// The set of streaming inputs from the client to the server.
	clientStream []interface{}
	// The set of streaming outputs from the server to the client.
	serverStream         []string
	expectedServerStream []interface{}
	finalResponse        interface{}
	err                  *verror.Standard
}

func sendServerStream(t *testing.T, controller *Controller, test *jsServerTestCase, w lib.ClientWriter) {
	for _, msg := range test.serverStream {
		controller.SendOnStream(0, msg, w)
	}

	serverReply := map[string]interface{}{
		"Results": []interface{}{test.finalResponse},
		"Err":     test.err,
	}

	bytes, err := json.Marshal(serverReply)
	if err != nil {
		t.Fatalf("Failed to serialize the reply: %v", err)
	}
	controller.HandleServerResponse(0, string(bytes))
}

func runJsServerTestCase(t *testing.T, test jsServerTestCase) {
	rt, err := serveServer()
	defer rt.mounttableServer.Stop()
	defer rt.proxyServer.Shutdown()
	defer rt.controller.Cleanup()

	if err != nil {
		t.Errorf("could not serve server %v", err)
	}

	if len(rt.writer.stream) != 1 {
		t.Errorf("expected only on response, got %d", len(rt.writer.stream))
		return
	}

	resp := rt.writer.stream[0]

	if resp.Type != lib.ResponseFinal {
		t.Errorf("unknown stream message Got: %v, expected: serve response", resp)
		return
	}

	msg, ok := resp.Message.(string)
	if !ok {
		t.Errorf("invalid endpdoint returned from serve: %v", resp.Message)
	}

	if _, err := r.NewEndpoint(msg); err != nil {
		t.Errorf("invalid endpdoint returned from serve: %v", resp.Message)
	}

	rt.writer.stream = nil

	// Create a client using app's runtime so it points to the right mounttable.
	client, err := rt.controller.rt.NewClient()

	if err != nil {
		t.Errorf("unable to create client: %v", err)
	}

	call, err := client.StartCall(rt.controller.rt.NewContext(), "/"+msg+"/adder", test.method, test.inArgs)
	if err != nil {
		t.Errorf("failed to start call: %v", err)
	}

	typedNames := rt.controller.rt.Identity().PublicID().Names()
	names := []interface{}{}
	for _, n := range typedNames {
		names = append(names, n)
	}
	expectedWebsocketMessage := []response{
		response{
			Type: lib.ResponseServerRequest,
			Message: map[string]interface{}{
				"ServerId": 0.0,
				"Method":   lib.LowercaseFirstCharacter(test.method),
				"Args":     test.inArgs,
				"Context": map[string]interface{}{
					"Name":   "adder",
					"Suffix": "adder",
					"RemoteID": map[string]interface{}{
						"Handle": 1.0,
						"Names":  names,
					},
				},
			},
		},
	}

	// Wait until the rpc has started.
	if err := rt.writer.waitForMessage(len(expectedWebsocketMessage)); err != nil {
		t.Errorf("didn't recieve expected message: %v", err)
	}
	for _, msg := range test.clientStream {
		expectedWebsocketMessage = append(expectedWebsocketMessage, response{Type: lib.ResponseStream, Message: msg})
		if err := call.Send(msg); err != nil {
			t.Errorf("unexpected error while sending %v: %v", msg, err)
		}
	}

	// Wait until all the streaming messages have been acknowledged.
	if err := rt.writer.waitForMessage(len(expectedWebsocketMessage)); err != nil {
		t.Errorf("didn't recieve expected message: %v", err)
	}

	expectedWebsocketMessage = append(expectedWebsocketMessage, response{Type: lib.ResponseStreamClose})

	expectedStream := test.expectedServerStream
	go sendServerStream(t, rt.controller, &test, rt.writer)
	for {
		var data interface{}
		if err := call.Recv(&data); err != nil {
			break
		}
		if len(expectedStream) == 0 {
			t.Errorf("unexpected stream value: %v", data)
			continue
		}
		if !reflect.DeepEqual(data, expectedStream[0]) {
			t.Errorf("unexpected stream value: got %v, expected %v", data, expectedStream[0])
		}
		expectedStream = expectedStream[1:]
	}
	var result interface{}
	var err2 error

	if err := call.Finish(&result, &err2); err != nil {
		t.Errorf("unexpected err :%v", err)
	}

	if !reflect.DeepEqual(result, test.finalResponse) {
		t.Errorf("unexected final response: got %v, expected %v", result, test.finalResponse)
	}

	// If err2 is nil and test.err is nil reflect.DeepEqual will return false because the
	// types are different.  Because of this, we only use reflect.DeepEqual if one of
	// the values is non-nil.  If both values are nil, then we consider them equal.
	if (err2 != nil || test.err != nil) && !reflect.DeepEqual(err2, test.err) {
		t.Errorf("unexected error: got %v, expected %v", err2, test.err)
	}

	// Wait until the close streaming messages have been acknowledged.
	if err := rt.writer.waitForMessage(len(expectedWebsocketMessage)); err != nil {
		t.Errorf("didn't recieve expected message: %v", err)
	}

	checkResponses(rt.writer, expectedWebsocketMessage, nil, t)
}

func TestSimpleJSServer(t *testing.T) {
	runJsServerTestCase(t, jsServerTestCase{
		method:        "Add",
		inArgs:        []interface{}{1.0, 2.0},
		finalResponse: 3.0,
	})
}

func TestJSServerWithError(t *testing.T) {
	runJsServerTestCase(t, jsServerTestCase{
		method:        "Add",
		inArgs:        []interface{}{1.0, 2.0},
		finalResponse: 3.0,
		err: &verror.Standard{
			ID:  verror.Internal,
			Msg: "JS Server failed",
		},
	})
}

func TestJSServerWihStreamingInputs(t *testing.T) {
	runJsServerTestCase(t, jsServerTestCase{
		method:        "StreamingAdd",
		inArgs:        []interface{}{},
		clientStream:  []interface{}{3.0, 4.0},
		finalResponse: 10.0,
	})
}

func TestJSServerWihStreamingOutputs(t *testing.T) {
	runJsServerTestCase(t, jsServerTestCase{
		method:               "StreamingAdd",
		inArgs:               []interface{}{},
		serverStream:         []string{"3", "4"},
		expectedServerStream: []interface{}{3.0, 4.0},
		finalResponse:        10.0,
	})
}

func TestJSServerWihStreamingInputsAndOutputs(t *testing.T) {
	runJsServerTestCase(t, jsServerTestCase{
		method:               "StreamingAdd",
		inArgs:               []interface{}{},
		clientStream:         []interface{}{1.0, 2.0},
		serverStream:         []string{"3", "4"},
		expectedServerStream: []interface{}{3.0, 4.0},
		finalResponse:        10.0,
	})
}

func TestDeserializeCaveat(t *testing.T) {
	C := func(cav security.Caveat, err error) security.Caveat {
		if err != nil {
			t.Fatal(err)
		}
		return cav
	}
	testCases := []struct {
		json          string
		expectedValue security.Caveat
	}{
		{
			json:          `{"_type":"MethodCaveat","service":"...","data":["Get","MultiGet"]}`,
			expectedValue: C(security.MethodCaveat("Get", "MultiGet")),
		},
		{
			json:          `{"_type":"PeerBlessingsCaveat","service":"...","data":["veyron.io/veyron/veyron/batman","veyron.io/veyron/veyron/brucewayne"]}`,
			expectedValue: C(security.PeerBlessingsCaveat("veyron.io/veyron/veyron/batman", "veyron.io/veyron/veyron/brucewayne")),
		},
	}

	for _, c := range testCases {
		var s jsonCaveatValidator
		if err := json.Unmarshal([]byte(c.json), &s); err != nil {
			t.Errorf("Failed to deserialize object: %v", err)
			return
		}

		caveat, err := decodeCaveat(s)
		if err != nil {
			t.Errorf("Failed to convert json caveat to go object: %v")
			return
		}

		if !reflect.DeepEqual(caveat, c.expectedValue) {
			t.Errorf("decoded produced the wrong value: got %v, expected %v", caveat, c.expectedValue)
		}
	}
}

func createChain(r veyron2.Runtime, name string) security.PrivateID {
	id := r.Identity()

	for _, component := range strings.Split(name, "/") {
		newID, err := r.NewIdentity(component)
		if err != nil {
			panic(err)
		}
		if id == nil {
			id = newID
			continue
		}
		blessedID, err := id.Bless(newID.PublicID(), component, time.Hour, nil)
		if err != nil {
			panic(err)
		}
		id, err = newID.Derive(blessedID)
		if err != nil {
			panic(err)
		}
	}
	return id
}

type mockSecurityContext struct {
	method  string
	localID security.PublicID
}

func makeMockSecurityContext(method string, name string) *mockSecurityContext {
	return &mockSecurityContext{
		method:  method,
		localID: createChain(r, name).PublicID(),
	}
}

func (m *mockSecurityContext) Method() string { return m.method }

func (m *mockSecurityContext) LocalID() security.PublicID { return m.localID }

func (*mockSecurityContext) Name() string { return "" }

func (*mockSecurityContext) Suffix() string { return "" }

func (*mockSecurityContext) Label() security.Label { return 0 }

func (*mockSecurityContext) Discharges() map[string]security.Discharge { return nil }

func (*mockSecurityContext) RemoteID() security.PublicID { return nil }

func (*mockSecurityContext) LocalEndpoint() naming.Endpoint { return nil }

func (*mockSecurityContext) RemoteEndpoint() naming.Endpoint { return nil }

type blessingTestCase struct {
	requestJSON             map[string]interface{}
	expectedValidateResults map[*mockSecurityContext]bool
	expectedErr             error
}

func runBlessingTest(c blessingTestCase, t *testing.T) {
	controller, err := NewController(nil, "mockVeyronProxyEP")

	if err != nil {
		t.Errorf("unable to create controller: %v", err)
		return
	}
	controller.AddIdentity(createChain(rt.R(), "test/bar").PublicID())

	bytes, err := json.Marshal(c.requestJSON)

	if err != nil {
		t.Errorf("failed to marshal request: %v", err)
		return
	}

	var request blessingRequest
	if err := json.Unmarshal(bytes, &request); err != nil {
		t.Errorf("failed to unmarshal request: %v", err)
		return
	}

	jsId, err := controller.bless(request)

	if !reflect.DeepEqual(err, c.expectedErr) {
		t.Errorf("error response does not match: expected %v, got %v", c.expectedErr, err)
		return
	}

	if err != nil {
		return
	}

	id := controller.idStore.Get(jsId.Handle)

	if id == nil {
		t.Errorf("couldn't get identity from store")
		return
	}

	for ctx, value := range c.expectedValidateResults {
		_, err := id.Authorize(ctx)
		if (err == nil) != value {
			t.Errorf("authorize failed to match expected value for %v: expected %v, got %v", ctx, value, err)
		}
	}
}

// The names of the identity in the mock contexts are root off the runtime's
// identity.  This function takes a name and prepends the runtime's identity's
// name.
func securityName(name string) string {
	return rt.R().Identity().PublicID().Names()[0] + "/" + name
}

func TestBlessingWithNoCaveats(t *testing.T) {
	runBlessingTest(blessingTestCase{
		requestJSON: map[string]interface{}{
			"handle":     1,
			"durationMs": 10000,
			"name":       "foo",
		},
		expectedValidateResults: map[*mockSecurityContext]bool{
			ctxFooAlice: true,
			ctxFooBob:   true,
			ctxBarAlice: true,
			ctxBarBob:   true,
		},
	}, t)
}

func TestBlessingWithMethodRestrictions(t *testing.T) {
	runBlessingTest(blessingTestCase{
		requestJSON: map[string]interface{}{
			"handle":     1,
			"durationMs": 10000,
			"caveats": []map[string]interface{}{
				map[string]interface{}{
					"_type":   "MethodCaveat",
					"service": security.AllPrincipals,
					"data":    []string{"Foo"},
				},
			},
			"name": "foo",
		},
		expectedValidateResults: map[*mockSecurityContext]bool{
			ctxFooAlice: true,
			ctxFooBob:   true,
			ctxBarAlice: false,
			ctxBarBob:   false,
		},
	}, t)
}

func TestBlessingWithPeerRestrictions(t *testing.T) {
	runBlessingTest(blessingTestCase{
		requestJSON: map[string]interface{}{
			"handle":     1,
			"durationMs": 10000,
			"caveats": []map[string]interface{}{
				map[string]interface{}{
					"_type":   "PeerBlessingsCaveat",
					"service": security.AllPrincipals,
					"data":    []string{securityName("test/alice")},
				},
			},
			"name": "foo",
		},
		expectedValidateResults: map[*mockSecurityContext]bool{
			ctxFooAlice: true,
			ctxFooBob:   false,
			ctxBarAlice: true,
			ctxBarBob:   false,
		},
	}, t)
}

func TestBlessingWithMethodAndPeerRestrictions(t *testing.T) {
	runBlessingTest(blessingTestCase{
		requestJSON: map[string]interface{}{
			"handle":     1,
			"durationMs": 10000,
			"caveats": []map[string]interface{}{
				map[string]interface{}{
					"_type":   "PeerBlessingsCaveat",
					"service": security.AllPrincipals,
					"data":    []string{securityName("test/alice")},
				},
				map[string]interface{}{
					"_type":   "MethodCaveat",
					"service": security.AllPrincipals,
					"data":    []string{"Bar"},
				},
			},
			"name": "foo",
		},
		expectedValidateResults: map[*mockSecurityContext]bool{
			ctxFooAlice: false,
			ctxFooBob:   false,
			ctxBarAlice: true,
			ctxBarBob:   false,
		},
	}, t)
}

func TestBlessingWhereBlesseeDoesNotExist(t *testing.T) {
	runBlessingTest(blessingTestCase{
		requestJSON: map[string]interface{}{
			"handle":     2,
			"durationMs": 10000,
			"name":       "foo",
		},
		expectedErr: verror.NoExistf("invalid PublicID handle"),
	}, t)
}
