package storage

import (
	"bytes"
	"context"
	"io"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/pingcap/errors"

	"github.com/tidbcloud/observability/pkg/diagcontroller/helper"
)

type OSSStorage struct {
	cli *oss.Client
}

func NewOSSStorage(region string) (Storage, error) {
	cli, err := helper.NewOSSCli(region)
	if err != nil {
		return nil, err
	}
	return &OSSStorage{
		cli: cli,
	}, nil
}

func (s *OSSStorage) LoadObject(bucket string, key string) ([]byte, error) {
	out, err := s.cli.GetObject(context.TODO(), &oss.GetObjectRequest{
		Bucket: oss.Ptr(bucket),
		Key:    oss.Ptr(key),
	})
	if err != nil {
		return nil, errors.Annotatef(err, "get object from s3 failed, bucket: %s, object key: %s", bucket, key)
	}
	defer out.Body.Close()
	data, err := io.ReadAll(out.Body)
	if err != nil {
		return nil, errors.Annotatef(err, "read object from oss failed, bucket: %s, object key: %s", bucket, key)
	}
	return data, nil
}

func (s *OSSStorage) UploadObject(bucket string, key string, data []byte) error {
	_, err := s.cli.PutObject(context.TODO(), &oss.PutObjectRequest{
		Bucket: aws.String(bucket),
		Key:    aws.String(key),
		Body:   bytes.NewReader(data),
	})

	if err != nil {
		return errors.Annotatef(err, "upload object to oss failed bucket: %s, object key: %s", bucket, key)
	}
	return nil
}
