/*
Copyright 2017 Google Inc. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package spanner

import (
	"errors"
	"fmt"
	"testing"
	"time"

	"github.com/golang/protobuf/proto"
	"github.com/golang/protobuf/ptypes"
	"golang.org/x/net/context"
	edpb "google.golang.org/genproto/googleapis/rpc/errdetails"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/metadata"
	"google.golang.org/grpc/status"
)

// Test if runRetryable loop deals with various errors correctly.
func TestRetry(t *testing.T) {
	if testing.Short() {
		t.SkipNow()
	}
	responses := []error{
		status.Errorf(codes.Internal, "transport is closing"),
		status.Errorf(codes.Unknown, "unexpected EOF"),
		status.Errorf(codes.Internal, "stream terminated by RST_STREAM with error code: 2"),
		status.Errorf(codes.Unavailable, "service is currently unavailable"),
		errRetry(fmt.Errorf("just retry it")),
	}
	err := runRetryable(context.Background(), func(ct context.Context) error {
		var r error
		if len(responses) > 0 {
			r = responses[0]
			responses = responses[1:]
		}
		return r
	})
	if err != nil {
		t.Errorf("runRetryable should be able to survive all retryable errors, but it returns %v", err)
	}
	// Unretryable errors
	injErr := errors.New("this is unretryable")
	err = runRetryable(context.Background(), func(ct context.Context) error {
		return injErr
	})
	if wantErr := toSpannerError(injErr); !testEqual(err, wantErr) {
		t.Errorf("runRetryable returns error %v, want %v", err, wantErr)
	}
	// Timeout
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	retryErr := errRetry(fmt.Errorf("still retrying"))
	err = runRetryable(ctx, func(ct context.Context) error {
		// Expect to trigger timeout in retryable runner after 10 executions.
		<-time.After(100 * time.Millisecond)
		// Let retryable runner to retry so that timeout will eventually happen.
		return retryErr
	})
	// Check error code and error message
	if wantErrCode, wantErr := codes.DeadlineExceeded, errContextCanceled(ctx, retryErr); ErrCode(err) != wantErrCode || !testEqual(err, wantErr) {
		t.Errorf("<err code, err>=\n<%v, %v>, want:\n<%v, %v>", ErrCode(err), err, wantErrCode, wantErr)
	}
	// Cancellation
	ctx, cancel = context.WithCancel(context.Background())
	retries := 3
	retryErr = errRetry(fmt.Errorf("retry before cancel"))
	err = runRetryable(ctx, func(ct context.Context) error {
		retries--
		if retries == 0 {
			cancel()
		}
		return retryErr
	})
	// Check error code, error message, retry count
	if wantErrCode, wantErr := codes.Canceled, errContextCanceled(ctx, retryErr); ErrCode(err) != wantErrCode || !testEqual(err, wantErr) || retries != 0 {
		t.Errorf("<err code, err, retries>=\n<%v, %v, %v>, want:\n<%v, %v, %v>", ErrCode(err), err, retries, wantErrCode, wantErr, 0)
	}
}

func TestRetryInfo(t *testing.T) {
	b, _ := proto.Marshal(&edpb.RetryInfo{
		RetryDelay: ptypes.DurationProto(time.Second),
	})
	trailers := map[string]string{
		retryInfoKey: string(b),
	}
	gotDelay, ok := extractRetryDelay(errRetry(toSpannerErrorWithMetadata(status.Errorf(codes.Aborted, ""), metadata.New(trailers))))
	if !ok || !testEqual(time.Second, gotDelay) {
		t.Errorf("<ok, retryDelay> = <%t, %v>, want <true, %v>", ok, gotDelay, time.Second)
	}
}
