package handler

import (
	"errors"
	"fmt"
	"testing"

	s3errors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
	"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer"
	"github.com/stretchr/testify/require"
)

func TestTransformS3Errors(t *testing.T) {
	for _, tc := range []struct {
		name     string
		err      error
		expected s3errors.ErrorCode
	}{
		{
			name:     "simple std error to internal error",
			err:      errors.New("some error"),
			expected: s3errors.ErrInternalError,
		},
		{
			name:     "layer access denied error to s3 access denied error",
			err:      layer.ErrAccessDenied,
			expected: s3errors.ErrAccessDenied,
		},
		{
			name:     "wrapped layer access denied error to s3 access denied error",
			err:      fmt.Errorf("wrap: %w", layer.ErrAccessDenied),
			expected: s3errors.ErrAccessDenied,
		},
		{
			name:     "layer node access denied error to s3 access denied error",
			err:      layer.ErrNodeAccessDenied,
			expected: s3errors.ErrAccessDenied,
		},
		{
			name:     "layer gateway timeout error to s3 gateway timeout error",
			err:      layer.ErrGatewayTimeout,
			expected: s3errors.ErrGatewayTimeout,
		},
		{
			name:     "s3 error to s3 error",
			err:      s3errors.GetAPIError(s3errors.ErrInvalidPart),
			expected: s3errors.ErrInvalidPart,
		},
		{
			name:     "wrapped s3 error to s3 error",
			err:      fmt.Errorf("wrap: %w", s3errors.GetAPIError(s3errors.ErrInvalidPart)),
			expected: s3errors.ErrInvalidPart,
		},
	} {
		t.Run(tc.name, func(t *testing.T) {
			err := transformToS3Error(tc.err)
			s3err, ok := err.(s3errors.Error)
			require.True(t, ok, "error must be s3 error")
			require.Equalf(t, tc.expected, s3err.ErrCode,
				"expected: '%s', got: '%s'",
				s3errors.GetAPIError(tc.expected).Code, s3errors.GetAPIError(s3err.ErrCode).Code)
		})
	}
}