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

import (
	"testing"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/options"
	"v.io/v23/rpc"
	"v.io/v23/security"
	"v.io/v23/verror"
	"v.io/x/ref/test"
)

var errRetryThis = verror.Register("retry_test.retryThis", verror.RetryBackoff, "retryable error")

type retryServer struct {
	called int // number of times TryAgain has been called
}

func (s *retryServer) TryAgain(ctx *context.T, _ rpc.ServerCall) error {
	// If this is the second time this method is being called, return success.
	if s.called > 0 {
		s.called++
		return nil
	}
	s.called++
	// otherwise, return a verror with action code RetryBackoff.
	return verror.New(errRetryThis, ctx)
}

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

	// Start the server.
	rs := retryServer{}
	_, server, err := v23.WithNewServer(ctx, "", &rs, security.AllowEveryone())
	if err != nil {
		t.Fatal(err)
	}
	name := server.Status().Endpoints[0].Name()

	client := v23.GetClient(ctx)
	// A traditional client.StartCall/call.Finish sequence should fail at
	// call.Finish since the error returned by the server won't be retried.
	call, err := client.StartCall(ctx, name, "TryAgain", nil)
	if err != nil {
		t.Errorf("client.StartCall failed: %v", err)
	}
	if err := call.Finish(); err == nil {
		t.Errorf("call.Finish should have failed")
	}
	rs.called = 0

	// A call to client.Call should succeed because the error return by the
	// server should be retried.
	if err := client.Call(ctx, name, "TryAgain", nil, nil); err != nil {
		t.Errorf("client.Call failed: %v", err)
	}
	// Ensure that client.Call retried the call exactly once.
	if rs.called != 2 {
		t.Errorf("retryServer should have been called twice, instead called %d times", rs.called)
	}
	rs.called = 0

	// The options.NoRetry option should be honored by client.Call, so the following
	// call should fail.
	if err := client.Call(ctx, name, "TryAgain", nil, nil, options.NoRetry{}); err == nil {
		t.Errorf("client.Call(..., options.NoRetry{}) should have failed")
	}
	// Ensure that client.Call did not retry the call.
	if rs.called != 1 {
		t.Errorf("retryServer have been called once, instead called %d times", rs.called)
	}
}
