package s3storage

import (
	"bytes"
	"context"
	"fmt"
	"io"
	"os"

	log "github.com/sirupsen/logrus"
)

type ScheduleTaskData struct {
	bucket   string
	prefix   string
	postfix  string
	localDir string
	cli      Client
}

func (s ScheduleTaskData) S3FileName(ctx context.Context, taskName string, timestamp int64) string {
	return fmt.Sprintf("%s/%s/%d.%s", s.prefix, taskName, timestamp, s.postfix)
}

func (s ScheduleTaskData) LocalDataFilePath(ctx context.Context, taskName string, timestamp int64) string {
	return fmt.Sprintf("%s/%s", s.localDir, s.S3FileName(ctx, taskName, timestamp))
}

func (s ScheduleTaskData) Download(ctx context.Context, taskName string, timestamp int64) (string, error) {
	s3FileName := s.S3FileName(ctx, taskName, timestamp)
	localFilePath := s.LocalDataFilePath(ctx, taskName, timestamp)
	out, err := s.cli.Get(ctx, s.bucket, s3FileName)
	if err != nil {
		log.Errorf("download data from s3 failed, s.bucket = %s, filePath = %s, err = %s", s.bucket, s3FileName, err.Error())
		return localFilePath, err
	}
	content, err := io.ReadAll(*out)
	if err != nil {
		log.Errorf("Read ScheduleTaskData file failed, s3FileName = %s, err = %s", s3FileName, err.Error())
		return localFilePath, err
	}
	if err := os.WriteFile(localFilePath, content, 0600); err != nil {
		log.Errorf("WriteFile failed, localFilePath = %s, err = %s", localFilePath, err.Error())
		return localFilePath, err
	}
	return localFilePath, err
}

func (s ScheduleTaskData) Upload(ctx context.Context, taskName string, timestamp int64) error {
	s3FileName := s.S3FileName(ctx, taskName, timestamp)
	localFilePath := s.LocalDataFilePath(ctx, taskName, timestamp)

	log.Infof("upload to s3, local_file=%s, s3_key=%s", localFilePath, s3FileName)
	b, err := os.ReadFile(localFilePath)
	if err != nil {
		log.Errorf("ReadFile failed, localFilePath = %s, err = %s", localFilePath, err.Error())
		return err
	}
	err = s.cli.Put(ctx, s.bucket, s3FileName, bytes.NewReader(b))
	if err != nil {
		log.Errorf("Upload file failed, err = %s", err.Error())
		return err
	}
	return nil
}

func BuildS3ScheduleTaskData(bucket string, prefix string, postfix string, cli Client, localDir string) ScheduleTaskData {
	return ScheduleTaskData{
		bucket:   bucket,
		prefix:   prefix,
		cli:      cli,
		localDir: localDir,
		postfix:  postfix,
	}
}
