/*
Copyright 2017 Google LLC

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 (
	"context"
	"errors"
	"strings"
	"testing"

	"github.com/googleapis/gax-go/v2/apierror"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

type wrappedTestError struct {
	wrapped error
	msg     string
}

func (w *wrappedTestError) Error() string {
	return w.msg
}

func (w *wrappedTestError) Unwrap() error {
	return w.wrapped
}

func TestToSpannerError(t *testing.T) {
	for _, test := range []struct {
		err              error
		wantCode         codes.Code
		wantMsg          string
		wantWrappedError error
	}{
		{errors.New("wha?"), codes.Unknown, `spanner: code = "Unknown", desc = "wha?"`, errors.New("wha?")},
		{context.Canceled, codes.Canceled, `spanner: code = "Canceled", desc = "context canceled"`, status.Errorf(codes.Canceled, "context canceled")},
		{context.DeadlineExceeded, codes.DeadlineExceeded, `spanner: code = "DeadlineExceeded", desc = "context deadline exceeded"`, status.Errorf(codes.DeadlineExceeded, "context deadline exceeded")},
		{status.Errorf(codes.ResourceExhausted, "so tired"), codes.ResourceExhausted, `spanner: code = "ResourceExhausted", desc = "so tired"`, status.Errorf(codes.ResourceExhausted, "so tired")},
		{spannerErrorf(codes.InvalidArgument, "bad"), codes.InvalidArgument, `spanner: code = "InvalidArgument", desc = "bad"`, status.Errorf(codes.InvalidArgument, "bad")},
		{&wrappedTestError{
			wrapped: spannerErrorf(codes.Aborted, "Transaction aborted"),
			msg:     "error with wrapped Spanner error",
		}, codes.Aborted, `spanner: code = "Aborted", desc = "Transaction aborted"`, status.Errorf(codes.Aborted, "Transaction aborted")},
		{&wrappedTestError{
			wrapped: errors.New("wha?"),
			msg:     "error with wrapped non-gRPC and non-Spanner error",
		}, codes.Unknown, `spanner: code = "Unknown", desc = "error with wrapped non-gRPC and non-Spanner error"`,
			&wrappedTestError{
				wrapped: errors.New("wha?"),
				msg:     "error with wrapped non-gRPC and non-Spanner error"}},
	} {
		err := ToSpannerError(test.err)
		errDuringCommit := toSpannerErrorWithCommitInfo(test.err, true)
		if got, want := ErrCode(err), test.wantCode; got != want {
			t.Errorf("%v: got %s, want %s", test.err, got, want)
		}
		converted := status.Convert(err)
		if converted.Code() != test.wantCode {
			t.Errorf("%v: got status %v, want status %v", test.err, converted.Code(), test.wantCode)
		}
		if got, want := err.Error(), test.wantMsg; got != want {
			t.Errorf("%v: got msg %s, want mgs %s", test.err, got, want)
		}
		if got, want := err.(*Error).err, test.wantWrappedError; got.Error() != want.Error() {
			t.Errorf("%v: Wrapped mismatch\nGot: %v\nWant: %v", test.err, got, want)
		}
		code := status.Code(errDuringCommit)
		gotWrappedDuringCommit := errDuringCommit.(*Error).err
		// Only DEADLINE_EXCEEDED and CANCELED should indicate that the
		// transaction outcome is unknown.
		if code == codes.DeadlineExceeded || code == codes.Canceled {
			if !strings.Contains(errDuringCommit.Error(), transactionOutcomeUnknownMsg) {
				t.Errorf(`%v: Missing %q from error during commit.\nGot: %v`, test.err, transactionOutcomeUnknownMsg, errDuringCommit)
			}
			wantWrappedDuringCommit := &TransactionOutcomeUnknownError{}
			if gotWrappedDuringCommit.Error() != wantWrappedDuringCommit.Error() {
				t.Errorf("%v: Wrapped commit error mismatch\nGot: %v\nWant: %v", test.err, gotWrappedDuringCommit, wantWrappedDuringCommit)
			}
		} else {
			if strings.Contains(errDuringCommit.Error(), transactionOutcomeUnknownMsg) {
				t.Errorf(`%v: Got unexpected %q in error during commit.\nGot: %v`, test.err, transactionOutcomeUnknownMsg, errDuringCommit)
			}
			wantWrappedDuringCommit := test.wantWrappedError
			if gotWrappedDuringCommit.Error() != wantWrappedDuringCommit.Error() {
				t.Errorf("%v: Wrapped commit error mismatch\nGot: %v\nWant: %v", test.err, gotWrappedDuringCommit, wantWrappedDuringCommit)
			}
		}
	}
}

func TestAPIErrorBackwardCompatibility(t *testing.T) {
	apiError, _ := apierror.FromError(status.Error(codes.InvalidArgument, "bad"))
	testCases := []struct {
		name        string
		clientError error
		want        *apierror.APIError
	}{
		{
			name:        "when client returns spanner.Error",
			clientError: spannerErrorf(codes.InvalidArgument, "bad"),
			want:        apiError,
		},
		{
			name:        "when client returns apierror.APIError",
			clientError: apiError,
			want:        apiError,
		},
	}
	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			var got *apierror.APIError
			ok := errorAs(tc.clientError, &got)
			if !ok {
				t.Error("error unwrapping spanner.Error to apierror.APIError")
			}
			if got.Error() != tc.want.Error() {
				t.Errorf("Wrapped error mismatch\nGot: %v\nWant: %v", got, tc.want)
			}
		})
	}
}
