package layer

import (
	"bytes"
	"crypto/rand"
	"crypto/sha256"
	"errors"
	"io"
	"testing"

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

func TestWrapReader(t *testing.T) {
	src := make([]byte, 1024*1024+1)
	_, err := rand.Read(src)
	require.NoError(t, err)
	h := sha256.Sum256(src)

	streamHash := sha256.New()
	reader := bytes.NewReader(src)
	wrappedReader := wrapReader(reader, 64*1024, func(buf []byte) {
		streamHash.Write(buf)
	})

	dst, err := io.ReadAll(wrappedReader)
	require.NoError(t, err)
	require.Equal(t, src, dst)
	require.Equal(t, h[:], streamHash.Sum(nil))
}

func TestGoroutinesDontLeakInPutAndHash(t *testing.T) {
	tc := prepareContext(t)

	content := make([]byte, 128*1024)
	_, err := rand.Read(content)
	require.NoError(t, err)
	payload := bytes.NewReader(content)

	prm := frostfs.PrmObjectCreate{
		Filepath: tc.obj,
		Payload:  payload,
	}

	expErr := errors.New("some error")
	tc.testFrostFS.SetObjectPutError(tc.obj, expErr)
	_, err = tc.layer.objectPutAndHash(tc.ctx, prm, tc.bktInfo)
	require.ErrorIs(t, err, expErr)
	require.Empty(t, payload.Len(), "body must be read out otherwise goroutines can leak in wrapReader")
}