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

// This test assumes the vdl packages under v.io/x/ref/lib/vdl/testdata have been
// compiled using the vdl binary, and runs end-to-end rpc tests against the
// generated output.  It's meant as a final sanity check of the vdl compiler; by
// using the compiled results we're behaving as an end-user would behave.

import (
	"errors"
	"math"
	"reflect"
	"testing"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/rpc"
	"v.io/v23/vdl"
	"v.io/x/ref/lib/vdl/testdata/arith"
	"v.io/x/ref/lib/vdl/testdata/base"
	"v.io/x/ref/test"

	_ "v.io/x/ref/profiles/static"
)

var generatedError = errors.New("generated error")

func newServer(ctx *context.T) rpc.Server {
	s, err := v23.NewServer(ctx)
	if err != nil {
		panic(err)
	}
	return s
}

// serverArith implements the arith.Arith interface.
type serverArith struct{}

func (*serverArith) Add(_ *context.T, _ rpc.ServerCall, A, B int32) (int32, error) {
	return A + B, nil
}

func (*serverArith) DivMod(_ *context.T, _ rpc.ServerCall, A, B int32) (int32, int32, error) {
	return A / B, A % B, nil
}

func (*serverArith) Sub(_ *context.T, _ rpc.ServerCall, args base.Args) (int32, error) {
	return args.A - args.B, nil
}

func (*serverArith) Mul(_ *context.T, _ rpc.ServerCall, nestedArgs base.NestedArgs) (int32, error) {
	return nestedArgs.Args.A * nestedArgs.Args.B, nil
}

func (*serverArith) Count(_ *context.T, call arith.ArithCountServerCall, start int32) error {
	const kNum = 1000
	for i := int32(0); i < kNum; i++ {
		if err := call.SendStream().Send(start + i); err != nil {
			return err
		}
	}
	return nil
}

func (*serverArith) StreamingAdd(_ *context.T, call arith.ArithStreamingAddServerCall) (int32, error) {
	var total int32
	for call.RecvStream().Advance() {
		value := call.RecvStream().Value()
		total += value
		call.SendStream().Send(total)
	}
	return total, call.RecvStream().Err()
}

func (*serverArith) GenError(_ *context.T, _ rpc.ServerCall) error {
	return generatedError
}

func (*serverArith) QuoteAny(_ *context.T, _ rpc.ServerCall, any *vdl.Value) (*vdl.Value, error) {
	return vdl.StringValue(any.String()), nil
}

type serverCalculator struct {
	serverArith
}

func (*serverCalculator) Sine(_ *context.T, _ rpc.ServerCall, angle float64) (float64, error) {
	return math.Sin(angle), nil
}

func (*serverCalculator) Cosine(_ *context.T, _ rpc.ServerCall, angle float64) (float64, error) {
	return math.Cos(angle), nil
}

func (*serverCalculator) Exp(_ *context.T, _ rpc.ServerCall, x float64) (float64, error) {
	return math.Exp(x), nil
}

func (*serverCalculator) On(_ *context.T, _ rpc.ServerCall) error {
	return nil
}

func (*serverCalculator) Off(_ *context.T, _ rpc.ServerCall) error {
	return nil
}

func TestCalculator(t *testing.T) {
	ctx, shutdown := test.InitForTest()
	defer shutdown()

	server := newServer(ctx)
	eps, err := server.Listen(v23.GetListenSpec(ctx))
	if err := server.Serve("", arith.CalculatorServer(&serverCalculator{}), nil); err != nil {
		t.Fatal(err)
	}
	root := eps[0].Name()
	// Synchronous calls
	calculator := arith.CalculatorClient(root)
	sine, err := calculator.Sine(ctx, 0)
	if err != nil {
		t.Errorf("Sine: got %q but expected no error", err)
	}
	if sine != 0 {
		t.Errorf("Sine: expected 0 got %f", sine)
	}
	cosine, err := calculator.Cosine(ctx, 0)
	if err != nil {
		t.Errorf("Cosine: got %q but expected no error", err)
	}
	if cosine != 1 {
		t.Errorf("Cosine: expected 1 got %f", cosine)
	}

	ar := arith.ArithClient(root)
	sum, err := ar.Add(ctx, 7, 8)
	if err != nil {
		t.Errorf("Add: got %q but expected no error", err)
	}
	if sum != 15 {
		t.Errorf("Add: expected 15 got %d", sum)
	}
	ar = calculator
	sum, err = ar.Add(ctx, 7, 8)
	if err != nil {
		t.Errorf("Add: got %q but expected no error", err)
	}
	if sum != 15 {
		t.Errorf("Add: expected 15 got %d", sum)
	}

	trig := arith.TrigonometryClient(root)
	cosine, err = trig.Cosine(ctx, 0)
	if err != nil {
		t.Errorf("Cosine: got %q but expected no error", err)
	}
	if cosine != 1 {
		t.Errorf("Cosine: expected 1 got %f", cosine)
	}

	// Test auto-generated methods.
	serverStub := arith.CalculatorServer(&serverCalculator{})
	expectDesc(t, serverStub.Describe__(), []rpc.InterfaceDesc{
		{
			Name:    "Calculator",
			PkgPath: "v.io/x/ref/lib/vdl/testdata/arith",
			Embeds: []rpc.EmbedDesc{
				{
					Name:    "Arith",
					PkgPath: "v.io/x/ref/lib/vdl/testdata/arith",
				},
				{
					Name:    "AdvancedMath",
					PkgPath: "v.io/x/ref/lib/vdl/testdata/arith",
				},
			},
			Methods: []rpc.MethodDesc{
				{Name: "On"},
				{Name: "Off", Tags: []*vdl.Value{vdl.StringValue("offtag")}},
			},
		},
		{
			Name:    "Arith",
			PkgPath: "v.io/x/ref/lib/vdl/testdata/arith",
			Methods: []rpc.MethodDesc{
				{
					Name:    "Add",
					InArgs:  []rpc.ArgDesc{{Name: "a"}, {Name: "b"}},
					OutArgs: []rpc.ArgDesc{{}},
				},
				{
					Name:    "DivMod",
					InArgs:  []rpc.ArgDesc{{Name: "a"}, {Name: "b"}},
					OutArgs: []rpc.ArgDesc{{Name: "quot"}, {Name: "rem"}},
				},
				{
					Name:    "Sub",
					InArgs:  []rpc.ArgDesc{{Name: "args"}},
					OutArgs: []rpc.ArgDesc{{}},
				},
				{
					Name:    "Mul",
					InArgs:  []rpc.ArgDesc{{Name: "nested"}},
					OutArgs: []rpc.ArgDesc{{}},
				},
				{
					Name: "GenError",
					Tags: []*vdl.Value{vdl.StringValue("foo"), vdl.StringValue("barz"), vdl.StringValue("hello"), vdl.Int32Value(129), vdl.Uint64Value(0x24)},
				},
				{
					Name:   "Count",
					InArgs: []rpc.ArgDesc{{Name: "start"}},
				},
				{
					Name:    "StreamingAdd",
					OutArgs: []rpc.ArgDesc{{Name: "total"}},
				},
				{
					Name:    "QuoteAny",
					InArgs:  []rpc.ArgDesc{{Name: "a"}},
					OutArgs: []rpc.ArgDesc{{}},
				},
			},
		},
		{
			Name:    "AdvancedMath",
			PkgPath: "v.io/x/ref/lib/vdl/testdata/arith",
			Embeds: []rpc.EmbedDesc{
				{
					Name:    "Trigonometry",
					PkgPath: "v.io/x/ref/lib/vdl/testdata/arith",
				},
				{
					Name:    "Exp",
					PkgPath: "v.io/x/ref/lib/vdl/testdata/arith/exp",
				}},
		},
		{
			Name:    "Trigonometry",
			PkgPath: "v.io/x/ref/lib/vdl/testdata/arith",
			Doc:     "// Trigonometry is an interface that specifies a couple trigonometric functions.",
			Methods: []rpc.MethodDesc{
				{
					Name: "Sine",
					InArgs: []rpc.ArgDesc{
						{"angle", ``}, // float64
					},
					OutArgs: []rpc.ArgDesc{
						{"", ``}, // float64
					},
				},
				{
					Name: "Cosine",
					InArgs: []rpc.ArgDesc{
						{"angle", ``}, // float64
					},
					OutArgs: []rpc.ArgDesc{
						{"", ``}, // float64
					},
				},
			},
		},
		{
			Name:    "Exp",
			PkgPath: "v.io/x/ref/lib/vdl/testdata/arith/exp",
			Methods: []rpc.MethodDesc{
				{
					Name: "Exp",
					InArgs: []rpc.ArgDesc{
						{"x", ``}, // float64
					},
					OutArgs: []rpc.ArgDesc{
						{"", ``}, // float64
					},
				},
			},
		},
	})
}

func TestArith(t *testing.T) {
	ctx, shutdown := test.InitForTest()
	defer shutdown()

	// TODO(bprosnitz) Split this test up -- it is quite long and hard to debug.

	// We try a few types of dispatchers on the server side, to verify that
	// anything dispatching to Arith or an interface embedding Arith (like
	// Calculator) works for a client looking to talk to an Arith service.
	objects := []interface{}{
		arith.ArithServer(&serverArith{}),
		arith.ArithServer(&serverCalculator{}),
		arith.CalculatorServer(&serverCalculator{}),
	}

	for i, obj := range objects {
		server := newServer(ctx)
		defer server.Stop()
		eps, err := server.Listen(v23.GetListenSpec(ctx))
		if err != nil {
			t.Fatal(err)
		}
		root := eps[0].Name()
		if err := server.Serve("", obj, nil); err != nil {
			t.Fatalf("%d: %v", i, err)
		}
		// Synchronous calls
		ar := arith.ArithClient(root)
		sum, err := ar.Add(ctx, 7, 8)
		if err != nil {
			t.Errorf("Add: got %q but expected no error", err)
		}
		if sum != 15 {
			t.Errorf("Add: expected 15 got %d", sum)
		}
		q, r, err := ar.DivMod(ctx, 7, 3)
		if err != nil {
			t.Errorf("DivMod: got %q but expected no error", err)
		}
		if q != 2 || r != 1 {
			t.Errorf("DivMod: expected (2,1) got (%d,%d)", q, r)
		}
		diff, err := ar.Sub(ctx, base.Args{7, 8})
		if err != nil {
			t.Errorf("Sub: got %q but expected no error", err)
		}
		if diff != -1 {
			t.Errorf("Sub: got %d, expected -1", diff)
		}
		prod, err := ar.Mul(ctx, base.NestedArgs{base.Args{7, 8}})
		if err != nil {
			t.Errorf("Mul: got %q, but expected no error", err)
		}
		if prod != 56 {
			t.Errorf("Sub: got %d, expected 56", prod)
		}
		stream, err := ar.Count(ctx, 35)
		if err != nil {
			t.Fatalf("error while executing Count %v", err)
		}

		countIterator := stream.RecvStream()
		for i := int32(0); i < 1000; i++ {
			if !countIterator.Advance() {
				t.Errorf("Error getting value %v", countIterator.Err())
			}
			val := countIterator.Value()
			if val != 35+i {
				t.Errorf("Expected value %d, got %d", 35+i, val)
			}
		}
		if countIterator.Advance() || countIterator.Err() != nil {
			t.Errorf("Reply stream should have been closed %v", countIterator.Err())
		}

		if err := stream.Finish(); err != nil {
			t.Errorf("Count failed with %v", err)
		}

		addStream, err := ar.StreamingAdd(ctx)

		go func() {
			sender := addStream.SendStream()
			for i := int32(0); i < 100; i++ {
				if err := sender.Send(i); err != nil {
					t.Errorf("Send error %v", err)
				}
			}
			if err := sender.Close(); err != nil {
				t.Errorf("Close error %v", err)
			}
		}()

		var expectedSum int32
		rStream := addStream.RecvStream()
		for i := int32(0); i < 100; i++ {
			expectedSum += i
			if !rStream.Advance() {
				t.Errorf("Error getting value %v", rStream.Err())
			}
			value := rStream.Value()
			if value != expectedSum {
				t.Errorf("Got %d but expected %d", value, expectedSum)
			}
		}

		if rStream.Advance() || rStream.Err() != nil {
			t.Errorf("Reply stream should have been closed %v", rStream.Err())
		}

		total, err := addStream.Finish()

		if err != nil {
			t.Errorf("Count failed with %v", err)
		}

		if total != expectedSum {
			t.Errorf("Got %d but expexted %d", total, expectedSum)
		}

		if err := ar.GenError(ctx); err == nil {
			t.Errorf("GenError: got %v but expected %v", err, generatedError)
		}

		// Server-side stubs

		serverStub := arith.ArithServer(&serverArith{})
		expectDesc(t, serverStub.Describe__(), []rpc.InterfaceDesc{
			{
				Name:    "Arith",
				PkgPath: "v.io/x/ref/lib/vdl/testdata/arith",
				Methods: []rpc.MethodDesc{
					{
						Name:    "Add",
						InArgs:  []rpc.ArgDesc{{Name: "a"}, {Name: "b"}},
						OutArgs: []rpc.ArgDesc{{}},
					},
					{
						Name:    "DivMod",
						InArgs:  []rpc.ArgDesc{{Name: "a"}, {Name: "b"}},
						OutArgs: []rpc.ArgDesc{{Name: "quot"}, {Name: "rem"}},
					},
					{
						Name:    "Sub",
						InArgs:  []rpc.ArgDesc{{Name: "args"}},
						OutArgs: []rpc.ArgDesc{{}},
					},
					{
						Name:    "Mul",
						InArgs:  []rpc.ArgDesc{{Name: "nested"}},
						OutArgs: []rpc.ArgDesc{{}},
					},
					{
						Name: "GenError",
						Tags: []*vdl.Value{vdl.StringValue("foo"), vdl.StringValue("barz"), vdl.StringValue("hello"), vdl.Int32Value(129), vdl.Uint64Value(0x24)},
					},
					{
						Name:   "Count",
						InArgs: []rpc.ArgDesc{{Name: "start"}},
					},
					{
						Name:    "StreamingAdd",
						OutArgs: []rpc.ArgDesc{{Name: "total"}},
					},
					{
						Name:    "QuoteAny",
						InArgs:  []rpc.ArgDesc{{Name: "a"}},
						OutArgs: []rpc.ArgDesc{{}},
					},
				},
			},
		})
	}
}

func expectDesc(t *testing.T, got, want []rpc.InterfaceDesc) {
	stripDesc(got)
	stripDesc(want)
	if !reflect.DeepEqual(got, want) {
		t.Errorf("Describe__ got %#v, want %#v", got, want)
	}
}

func stripDesc(desc []rpc.InterfaceDesc) {
	// Don't bother testing the documentation, to avoid spurious changes.
	for i := range desc {
		desc[i].Doc = ""
		for j := range desc[i].Embeds {
			desc[i].Embeds[j].Doc = ""
		}
		for j := range desc[i].Methods {
			desc[i].Methods[j].Doc = ""
			for k := range desc[i].Methods[j].InArgs {
				desc[i].Methods[j].InArgs[k].Doc = ""
			}
			for k := range desc[i].Methods[j].OutArgs {
				desc[i].Methods[j].OutArgs[k].Doc = ""
			}
			desc[i].Methods[j].InStream.Doc = ""
			desc[i].Methods[j].OutStream.Doc = ""
		}
	}
}
