package s3storage

import (
	"bytes"
	"context"
	"io/ioutil"
	"os"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/tidbcloud/metering/pkg/errors"
	"github.com/tidbcloud/metering/test/mocks3storage"
	"go.uber.org/mock/gomock"
)

func TestScheduleTaskData_Download_and_Upload(t *testing.T) {
	os.MkdirAll("testdata/prefix/test/", 0755)
	ctrl := gomock.NewController(t)
	mockClient := mocks3storage.NewMockClient(ctrl)

	rc := ioutil.NopCloser(bytes.NewBufferString("datadata"))

	mockClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(&rc, nil).Times(2)

	d := ScheduleTaskData{
		bucket:   "bucket",
		prefix:   "prefix",
		postfix:  "postfix",
		localDir: "testdata",

		cli: mockClient,
	}

	f, err := d.Download(context.TODO(), "test", 111)
	assert.NoError(t, err)
	assert.Equal(t, "testdata/prefix/test/111.postfix", f)

	_, err = d.Download(context.TODO(), "aaaa", 111)
	assert.Error(t, err)

	mockClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New(errors.S3Error, "")).Times(1)
	_, err = d.Download(context.TODO(), "test", 111)
	assert.Error(t, err)

	mockClient.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1)
	err = d.Upload(context.TODO(), "test", 111)
	assert.NoError(t, err)
	mockClient.EXPECT().Put(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New(errors.OSError, "")).Times(1)
	err = d.Upload(context.TODO(), "test", 111)
	assert.Error(t, err)
}

func TestScheduleTaskData_file_not_exist(t *testing.T) {
	ctrl := gomock.NewController(t)
	mockClient := mocks3storage.NewMockClient(ctrl)

	d := ScheduleTaskData{
		bucket:   "ssss",
		prefix:   "prefix",
		postfix:  "postfix",
		localDir: "ssss",

		cli: mockClient,
	}

	err := d.Upload(context.TODO(), "test", 111)
	assert.Error(t, err)

}

func TestScheduleTaskData_LocalDataFilePath(t *testing.T) {
	ctrl := gomock.NewController(t)
	mockClient := mocks3storage.NewMockClient(ctrl)

	d := ScheduleTaskData{
		bucket:   "bucket",
		prefix:   "prefix",
		postfix:  "postfix",
		localDir: "testdata",

		cli: mockClient,
	}
	s := d.LocalDataFilePath(context.TODO(), "test", 1111)
	assert.Equal(t, "testdata/prefix/test/1111.postfix", s)
}

func TestScheduleTaskData_S3FileName(t *testing.T) {

	ctrl := gomock.NewController(t)
	mockClient := mocks3storage.NewMockClient(ctrl)

	d := BuildS3ScheduleTaskData("bucket", "prefix", "postfix", mockClient, "testdata")
	s := d.S3FileName(context.TODO(), "test", 1111)
	assert.Equal(t, "prefix/test/1111.postfix", s)
}
