package frostfs

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

	"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer"
	errorsFrost "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/errors"
	apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
	"github.com/stretchr/testify/require"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

func TestErrorChecking(t *testing.T) {
	reason := "some reason"
	err := new(apistatus.ObjectAccessDenied)
	err.WriteReason(reason)

	var wrappedError error

	if fetchedReason, ok := errorsFrost.IsErrObjectAccessDenied(err); ok {
		wrappedError = fmt.Errorf("%w: %s", layer.ErrAccessDenied, fetchedReason)
	}

	require.ErrorIs(t, wrappedError, layer.ErrAccessDenied)
	require.Contains(t, wrappedError.Error(), reason)
}

func TestErrorTimeoutChecking(t *testing.T) {
	t.Run("simple timeout", func(t *testing.T) {
		require.True(t, errorsFrost.IsTimeoutError(errors.New("timeout")))
	})

	t.Run("deadline exceeded", func(t *testing.T) {
		ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond)
		defer cancel()
		time.Sleep(50 * time.Millisecond)

		require.True(t, errorsFrost.IsTimeoutError(ctx.Err()))
	})

	t.Run("grpc deadline exceeded", func(t *testing.T) {
		err := fmt.Errorf("wrap grpc error: %w", status.Error(codes.DeadlineExceeded, "error"))
		require.True(t, errorsFrost.IsTimeoutError(err))
	})
}