package s3storage

import (
	"bytes"
	"context"
	"os"
	"testing"

	"github.com/aws/aws-sdk-go-v2/aws"
	s3api "github.com/aws/aws-sdk-go-v2/service/s3"
	"github.com/stretchr/testify/assert"
	"github.com/tidbcloud/metering/pkg/errors"
	"github.com/tidbcloud/metering/test/mocks3storage"
	"go.uber.org/mock/gomock"
)

func newMockS3(cfg aws.Config, mock s3Client) S3Client {
	return S3Client{
		cli: mock,
		cfg: cfg,
	}
}

func TestS3GetObject(t *testing.T) {
	ctl := gomock.NewController(t)
	defer ctl.Finish()
	var cfg aws.Config
	mockclient := mocks3storage.NewMocks3Client(ctl)
	s3client := newMockS3(cfg, mockclient)
	mockclient.EXPECT().GetObject(gomock.Any(), gomock.Any()).Return(nil, errors.New(errors.UnrecognizedError, ""))
	_, err := s3client.Get(context.TODO(), "", "")
	assert.Error(t, err)

	mockclient.EXPECT().GetObject(gomock.Any(), gomock.Any()).Return(&s3api.GetObjectOutput{
		Body: nil,
	}, nil)
	_, err = s3client.Get(context.TODO(), "", "")
	assert.NoError(t, err)

}

func TestS3PutObject(t *testing.T) {
	ctl := gomock.NewController(t)
	defer ctl.Finish()
	var cfg aws.Config
	mockclient := mocks3storage.NewMocks3Client(ctl)
	s3client := newMockS3(cfg, mockclient)
	mockclient.EXPECT().PutObject(gomock.Any(), gomock.Any()).Return(nil, errors.New(errors.UnrecognizedError, ""))
	err := s3client.Put(context.TODO(), "", "", nil)
	assert.Error(t, err)

	mockclient.EXPECT().PutObject(gomock.Any(), gomock.Any()).Return(&s3api.PutObjectOutput{}, nil)
	r := bytes.NewReader([]byte(""))
	err = s3client.Put(context.TODO(), "", "", r)
	assert.NoError(t, err)

}

func TestPrepareS3Client(t *testing.T) {
	os.Setenv("AWS_ACCESS_KEY_ID", "test1")
	os.Setenv("AWS_SECRET_ACCESS_KEY", "testsec")
	defer os.Unsetenv("AWS_SECRET_ACCESS_KEY")
	defer os.Unsetenv("AWS_ACCESS_KEY_ID")
	ctx := context.TODO()
	cli := PrepareS3Client(ctx, "aws", "us-west-2", "test")
	assert.NotNil(t, cli)
}
