package amazons3

import (
	"bytes"
	"context"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
	"server/utility/oss"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/s3/s3manager"
	"github.com/gogf/gf/crypto/gmd5"
	"github.com/gogf/gf/os/gfile"
	"github.com/gogf/gf/os/glog"
	"github.com/gogf/gf/os/gtime"
	"github.com/gogf/gf/util/grand"
)

type AmazonS3Client struct {
	key    string
	secret string
	region string
	bucket string
	sess   *session.Session
}

var amazonS3Client *AmazonS3Client

func (c *AmazonS3Client) Upload(file *ghttp.UploadFile, folder string) (string, error) {
	uploader := s3manager.NewUploader(c.sess)
	f, err := file.Open()
	if err != nil {
		return "", err
	}
	defer f.Close()
	body := make([]byte, file.Size)
	_, err = f.Read(body)
	if err != nil {
		return "", err
	}
	key, err := gmd5.Encrypt(file.Filename + gtime.Datetime() + grand.Digits(6))
	ext := gfile.Ext(file.Filename)
	if err != nil {
		return "", err
	}
	r, err := uploader.Upload(&s3manager.UploadInput{
		Bucket: aws.String(c.bucket),
		Key:    aws.String(folder + "/" + key + ext),
		Body:   bytes.NewReader(body),
	})
	if err != nil {
		return "", err
	}
	return r.Location, nil
}

func (c *AmazonS3Client) UploadLocalFile(path, name string) (string, error) {
	uploader := s3manager.NewUploader(c.sess)
	f, err := gfile.Open(path)
	if err != nil {
		return "", err
	}
	defer f.Close()
	body := make([]byte, gfile.Size(path))
	_, err = f.Read(body)
	if err != nil {
		return "", err
	}
	r, err := uploader.Upload(&s3manager.UploadInput{
		Bucket: aws.String(c.bucket),
		Key:    aws.String(name),
		Body:   bytes.NewReader(body),
	})
	if err != nil {
		glog.Debug(err)
		return "", err
	}
	return r.Location, nil
}

func init() {
	ctx := context.Background()
	key := g.Config().MustGet(ctx, "oss.s3.key").String()
	secret := g.Config().MustGet(ctx, "oss.s3.secret").String()
	region := g.Config().MustGet(ctx, "oss.s3.region").String()
	bucket := g.Config().MustGet(ctx, "oss.s3.bucket").String()

	if key == "" || secret == "" || region == "" || bucket == "" {
		glog.Error("请配置 OSS 配置")
	}
	config := &aws.Config{
		Region:      aws.String(region),
		Credentials: credentials.NewStaticCredentials(key, secret, ""),
	}
	sess := session.Must(session.NewSession(config))
	amazonS3Client := AmazonS3Client{
		bucket: bucket,
		key:    key,
		region: region,
		secret: secret,
		sess:   sess,
	}
	oss.RegisterClient("amazon_s3", &amazonS3Client)
}
