// 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"
)

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 = ""
		}
	}
}
