package internal

import (
	"bytes"
	"context"
	"filesdk"
	"fmt"
	"github.com/gogf/gf/v2/os/glog"
	"yx-dataset-server/app/schema"
	"yx-dataset-server/library/logger"
	"yx-dataset-server/library/minio"
	"yx-dataset-server/library/utils"

	"io"
	"net/http"
	"net/url"
	"strings"
)

// NewFile 创建文件管理实例
func NewFile() *File {
	return &File{}
}

// File 文件管理
type File struct{}

// Upload 上传文件
func (a *File) Upload(ctx context.Context, r *http.Request, formKey, bucket string) (*schema.FileInfo, error) {
	file, header, err := r.FormFile(formKey)
	if err != nil {
		return nil, err
	}
	buff := new(bytes.Buffer)
	_, err = io.Copy(buff, file)
	if err != nil {
		return nil, err
	}
	headers := map[string]string{}
	headers["FILE-EXPIRE"] = utils.GetConfig("file_server.file-expire").String()
	result, err := filesdk.GetHandle().Upload(header.Filename, bucket, headers, buff.Bytes())
	if err != nil {
		glog.Debugf(ctx, "上传文件失败:%s", err.Error())
		return nil, err
	}
	err = filesdk.GetHandle().HandlePersistent(result.Hash)
	if err != nil {
		logger.Printf(ctx, "文件持久化设置失败：%s", err.Error())
	}
	//uuid := guid.S()
	//ctx = fuh.NewFileNameContext(ctx, func(ctx fuh.ContextInfo) string {
	//	return fmt.Sprintf("%s/%s/%s/%s", ctx.BasePath(), strings.ToLower(bucket), uuid, a.getFileName(ctx.FileName()))
	//})
	//infos, err := fuh.Upload(ctx, r, formKey)
	//if err != nil {
	//	return nil, err
	//} else if len(infos) == 0 {
	//	return nil, nil
	//}
	//
	//fullName := fmt.Sprintf("%s/%s/%s/%s", utils.GetConfig("file_upload.prefix"), strings.ToLower(bucket), uuid, url.PathEscape(a.getFileName(infos[0].Name())))
	//if fullName[0] != '/' {
	//	fullName = "/" + fullName
	//}

	info := &schema.FileInfo{
		URL:  result.URL,
		Name: result.Name,
		Size: result.Size,
		MD5:  result.Hash,
	}

	return info, nil
}

// Download 下载文件
func (a *File) Download(ctx context.Context, fileUrl string) ([]byte, string, error) {
	Url, err := url.PathUnescape(fileUrl)
	if err != nil {
		return nil, "", err
	}
	stat, err := minio.GetClient().Stat(Url)
	if err != nil {
		fmt.Println("文件不存在")
		return nil, "", err
	}
	fileData, err := a.getSourceFileData(ctx, Url)
	if err != nil {
		return nil, "", err
	}

	return fileData, stat.ContentType, nil

}

func (a *File) getSourceFileData(ctx context.Context, file string) ([]byte, error) {
	var fileData []byte
	obj, err := minio.GetClient().Get(ctx, file)
	if err != nil {
		return nil, err
	}
	buf := new(bytes.Buffer)
	_, _ = io.Copy(buf, obj)

	_ = obj.Close()
	fileData = buf.Bytes()
	return fileData, nil
}

// 修正文件名，将半角 % 替换为全角 ％（不替换的话文件将无法从浏览器中打开）
func (a *File) getFileName(fileName string) string {
	return strings.ReplaceAll(fileName, "%", "％")
}
