package oss

import (
	"context"
	"errors"
	"eta_gn/eta_obs/global"
	"fmt"
	"github.com/minio/minio-go/v7"
	"github.com/minio/minio-go/v7/pkg/credentials"
	"io"
	"log"
	"time"
)

type MinioOss struct{}

// UploadFile 上传文件
func (m *MinioOss) UploadFile(fileName, filePath, savePath string) (string, error) {
	if global.CONFIG.Oss.AccessKeyId == `` || global.CONFIG.Oss.AccessKeySecret == `` {
		return "0", errors.New("MinIo信息未配置")
	}

	ctx := context.Background()
	bucketName := global.CONFIG.Oss.BucketName

	path := savePath
	if savePath == "" {
		path = global.CONFIG.Oss.UploadDir + time.Now().Format("200601/20060102/") + fileName
	}
	_, err := global.MinioClient.FPutObject(ctx, bucketName, path, filePath, minio.PutObjectOptions{})
	if err != nil {
		log.Println(err)
		return "3", err
	}
	resourceUrl := global.CONFIG.Oss.ImgHost + path
	return resourceUrl, err
}

func (m *MinioOss) GetUploadToken() (token OssToken, err error) {
	useSsl := "1"
	if !global.CONFIG.Oss.DisableSSL {
		useSsl = `0`
	}
	token.AccessKeyId = global.CONFIG.Oss.AccessKeyId
	token.SecretKeyId = global.CONFIG.Oss.AccessKeySecret
	token.Endpoint = global.CONFIG.Oss.EndPoint
	token.ImgHost = global.CONFIG.Oss.ImgHost
	token.Bucketname = global.CONFIG.Oss.BucketName
	token.UseSSL = useSsl
	token.RegionId = global.CONFIG.Oss.RegionId
	token.Port = global.CONFIG.Oss.Port
	return
}

// InitMinio
// @Description: 初始化minio客户端
// @author: Roc
// @datetime 2024-10-25 18:14:10
func InitMinio() {
	if global.CONFIG.Oss.AccessKeyId == `` || global.CONFIG.Oss.AccessKeySecret == `` {
		panic("MinIo信息未配置")
		return
	}

	ctx := context.Background()
	// 此处兼容一下前后端endpoint不一致的情况, 前端用minio_endpoint后端用minio_back_endpoint, minio_back_endpoint为空则都取前者
	endpoint := global.CONFIG.Oss.EndPoint
	if global.CONFIG.Oss.BackEndPoint != "" {
		endpoint = global.CONFIG.Oss.BackEndPoint
	}
	accessKeyID := global.CONFIG.Oss.AccessKeyId
	secretAccessKey := global.CONFIG.Oss.AccessKeySecret
	useSSL := false
	if !global.CONFIG.Oss.DisableSSL {
		useSSL = true
	}
	minioClient, err := minio.New(endpoint, &minio.Options{
		Creds:  credentials.NewStaticV4(accessKeyID, secretAccessKey, ""),
		Secure: useSSL,
	})
	if err != nil {
		panic("minio链接建立失败" + err.Error())
		return
	}
	bucketName := global.CONFIG.Oss.BucketName
	exists, errBucketExists := minioClient.BucketExists(ctx, bucketName)
	if errBucketExists != nil || !exists {
		panic(fmt.Sprintf("BucketExists: %v; err: %v", exists, errBucketExists))
		return
	}

	global.MinioClient = minioClient
}

// GetFile
// @Description: 读取s3文件的资源
// @author: Roc
// @receiver m
// @datetime 2024-10-25 18:15:58
// @param filePath string
// @return buffer []byte
// @return contentType string
// @return err error
func (m *MinioOss) GetFile(filePath string) (buffer []byte, contentType string, err error) {
	if global.MinioClient == nil {
		err = errors.New("MinIo客户端未初始化")
		return
	}

	ctx := context.Background()
	bucketName := global.CONFIG.Oss.BucketName

	// 获取文件元数据
	objectInfo, err := global.MinioClient.StatObject(ctx, bucketName, filePath, minio.StatObjectOptions{})
	if err != nil {
		log.Println("获取源数据失败,err:", err)
		return
	}

	//log.Println(objectInfo)

	// 获取文件的 MIME 类型
	contentType = objectInfo.ContentType

	// 获取对象
	obj, err := global.MinioClient.GetObject(ctx, bucketName, filePath, minio.GetObjectOptions{})
	if err != nil {
		log.Println(err)
		return
	}
	if err != nil {
		//log.Println(err)
		return
	}
	defer func() {
		_ = obj.Close()
	}()

	// 读取对象到字节切片
	//var buffer []byte
	buffer, err = io.ReadAll(obj)
	if err != nil {
		//log.Println(err)
		return
	}

	return
}