package grpcli

import (
	"testing"

	"github.com/stretchr/testify/require"
	"github.com/tidbcloud/pkgv2/bizerr"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

func TestGrpcStatus2BizError(t *testing.T) {
	t.Parallel()

	// bizerr escalates internal codes on construction, so the expectation for
	// an internal code has to be built the same way rather than written out.
	escalatedUnknown := bizerr.New(bizerr.ErrCodeUnknown, "x").ErrCode()

	cases := []struct {
		name string
		code codes.Code
		want bizerr.ErrCode
	}{
		{"standard not found", codes.NotFound, bizerr.ErrCodeRecordNotFound},
		{"standard invalid argument", codes.InvalidArgument, bizerr.ErrCodeParams},
		{"unmapped standard code", codes.Internal, escalatedUnknown},
		// TiDB Cloud services answer with their bizerr code in the status code
		// slot instead of translating it to a standard gRPC code. The
		// management Export service reports a missing Export this way, and the
		// reuse-or-create lifecycle only stays idempotent if it still reads as
		// not-found rather than collapsing into ErrCodeUnknown.
		{
			"bizerr code passed through",
			codes.Code(bizerr.ErrCodeRecordNotFound),
			bizerr.ErrCodeRecordNotFound,
		},
		{
			"bizerr params code passed through",
			codes.Code(bizerr.ErrCodeParams),
			bizerr.ErrCodeParams,
		},
	}

	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			t.Parallel()

			err := GrpcStatus2BizError(status.New(tc.code, "boom"))
			require.NotNil(t, err)
			require.Equal(t, tc.want, err.ErrCode())
			require.Contains(t, err.Error(), "boom")
		})
	}
}
