package oss

import (
	"bytes"
	"errors"
	"git.sxidc.com/go-tools/utils/strutils"
	"github.com/aliyun/aliyun-oss-go-sdk/oss"
	"io"
	"log"
)

var Bkt *oss.Bucket
var pfx string

func Init(endpoint, keyID, keySecret, prefix string) error {
	pfx = prefix

	client, err := oss.New(endpoint, keyID, keySecret)
	if err != nil {
		return err
	}

	Bkt, err = client.Bucket("fs-yf")
	if err != nil {
		return err
	}

	return nil
}

func Touch(reader io.Reader, to string) error {
	return TouchPrefix(reader, to, true)
}

func TouchPrefix(reader io.Reader, to string, addPfx bool) error {
	if addPfx {
		return Bkt.PutObject(pfx+to, reader)
	}
	return Bkt.PutObject(to, reader)
}

func Url(obj string) (string, error) {
	return UrlPfx(obj, true)
}

func UrlPfx(obj string, addPfx bool) (string, error) {
	if strutils.HasBlank(obj) {
		log.Println("oss获取Url发现违规参数")
		return "", nil
	}

	if addPfx {
		return Bkt.SignURL(pfx+obj, oss.HTTPGet, 60*60*60*365)
	}

	return Bkt.SignURL(obj, oss.HTTPGet, 60*60*60*365)
}

func ZoomUrl(obj, s string) (string, error) {
	if strutils.HasBlank(obj) {
		log.Println("oss发现违规参数")
		return "", nil
	}
	return Bkt.SignURL(pfx+obj, oss.HTTPGet, 60, oss.Process(s))
}

func ZoomUrlPfx(obj, s string, addPfx bool) (string, error) {
	if strutils.HasBlank(obj) {
		log.Println("oss发现违规参数")
		return "", nil
	}

	if addPfx {
		return Bkt.SignURL(pfx+obj, oss.HTTPGet, 60, oss.Process(s))
	}

	return Bkt.SignURL(obj, oss.HTTPGet, 60, oss.Process(s))

}

func Exist(obj string) (bool, error) {
	if strutils.HasBlank(obj) {
		return false, nil
	}

	return Bkt.IsObjectExist(pfx + obj)
}

func Rm(objs ...string) error {
	L := len(objs)
	if L == 0 {
		return nil
	}

	result, err := Bkt.DeleteObjects(objs)
	if err != nil {
		return err
	}

	if len(result.DeletedObjects) != L {
		go func() {
			// 日志打印哪些Obj删除失败
			sucMap := make(map[string]struct{}, len(result.DeletedObjects))
			for _, deleted := range result.DeletedObjects {
				sucMap[deleted] = struct{}{}
			}

			for _, obj := range objs {
				if _, ok := sucMap[obj]; !ok {
					log.Println("Oss删除%s图片失败")
				}
			}
		}()
	}

	return nil
}

func Ls(dir string) ([]string, error) {
	if strutils.HasBlank(dir) {
		return []string{}, nil
	}

	v2, err := Bkt.ListObjectsV2(oss.Prefix(pfx + dir))
	if err != nil {
		return nil, err
	}

	ks := make([]string, len(v2.Objects))
	for i, obj := range v2.Objects {
		ks[i] = obj.Key
	}

	return ks, nil
}

func Mv(f, t string) error {
	if err := Cp(f, t); err != nil {
		return err
	}

	return Bkt.DeleteObject(pfx + f)
}

func CpOrigin(f, t string) error {
	_, err := Bkt.CopyObject(f, t)
	return err
}

func Cp(f, t string) error {
	return CpOrigin(pfx+f, pfx+t)
}

func TouchFormatImg(reader io.Reader, to string) error {
	if reader == nil || strutils.HasBlank(to) {
		log.Println("oss上传发现违规参数")
		return nil
	}

	return Bkt.PutObject(pfx+to, reader, oss.ContentType("image/jpg"))
}

func GetObjectBytes(obj string) ([]byte, error) {
	if strutils.HasBlank(obj) {
		return nil, errors.New("参数错误")
	}
	buf := new(bytes.Buffer)
	body, err := Bkt.GetObject(pfx + obj)
	if err != nil {
		return nil, err
	}
	_, err = io.Copy(buf, body)
	if err != nil {
		return nil, err
	}
	err = body.Close()
	if err != nil {
		return nil, err
	}

	return buf.Bytes(), nil
}

func MvWithoutPrefix(f, t string) error {
	if _, err := Bkt.CopyObject(f, t); err != nil {
		return err
	}

	return Bkt.DeleteObject(f)
}