package services

import (
	"encoding/json"
	"errors"
	"github.com/aliyun/alibaba-cloud-sdk-go/services/sts"
	"github.com/aliyun/aliyun-oss-go-sdk/oss"
	"hongze/hongze_open_api/services/alarm_msg"
	"hongze/hongze_open_api/utils"
	"os"
	"time"
)

/*
上传demo
func init() {
	fmt.Println("start")
	randStr := utils.GetRandStringNoSpecialChar(28)
	fileName :=  randStr + ".jpg"
	fmt.Println("fileName:",fileName)
	fpath:="./1.png"
	resourceUrl,err:=UploadAliyun(fileName,fpath)
	if err!=nil {
		fmt.Println("UploadAliyun Err:",err.Error())
		return
	}
	fmt.Println("resourceUrl:",resourceUrl)
	fmt.Println("end")
}
*/

//图片上传到阿里云
func UploadAliyun(filename, filepath string) (string, error) {
	client, err := oss.New(utils.Endpoint, utils.AccessKeyId, utils.AccessKeySecret)
	if err != nil {
		return "1", err
	}
	bucket, err := client.Bucket(utils.Bucketname)
	if err != nil {
		return "2", err
	}
	path := utils.Upload_dir + time.Now().Format("200601/20060102/")
	path += filename
	err = bucket.PutObjectFromFile(path, filepath)
	if err != nil {
		return "3", err
	}
	path = utils.Imghost + path
	return path, err
}

//音频上传到阿里云
func UploadAudioAliyun(filename, filepath string) (string, error) {
	client, err := oss.New(utils.Endpoint, utils.AccessKeyId, utils.AccessKeySecret)
	if err != nil {
		return "1", err
	}
	bucket, err := client.Bucket(utils.Bucketname)
	if err != nil {
		return "2", err
	}
	path := utils.Upload_Audio_Dir + time.Now().Format("200601/20060102/")
	path += filename
	err = bucket.PutObjectFromFile(path, filepath)
	if err != nil {
		return "3", err
	}
	path = utils.Imghost + path
	return path, err
}

//视频上传到阿里云
func UploadVideoAliyun(filename, filepath, savePath string) error {
	defer func() {
		os.Remove(filepath)
	}()
	client, err := oss.New(utils.Endpoint, utils.AccessKeyId, utils.AccessKeySecret)
	if err != nil {
		return err
	}
	bucket, err := client.Bucket(utils.Bucketname)
	if err != nil {
		return err
	}
	//path := utils.Upload_Audio_Dir + time.Now().Format("200601/20060102/")
	//path += filename
	err = bucket.PutObjectFromFile(savePath, filepath)
	if err != nil {
		return err
	}
	//path = utils.Imghost + path
	//return path,err
	return err
}

var (
	RoleArn            = "acs:ram::1884217364581072:role/hzossrole"
	RoleSessionName    = "hzossRole"
	RAMAccessKeyId     = "LTAI5t9S36LXduhTnECVY6Hn"
	RAMAccessKeySecret = "V6FG5bdzjKKqMpqEqxeWijJCdzDCuL"
	STSTokenCacheKey   = "hongze_admin_sts_token"
)

type STSToken struct {
	AccessKeyId     string
	AccessKeySecret string
	SecurityToken   string
	ExpiredTime     string
}

// GetOssSTSToken 获取STSToken
func GetOssSTSToken() (item *STSToken, err error) {
	defer func() {
		if err != nil {
			utils.FileLog.Info(err.Error())
			go alarm_msg.SendAlarmMsg("获取STSToken失败, ErrMsg: "+err.Error(), 3)
		}
	}()
	item = new(STSToken)
	// 获取缓存中的Token
	recent, _ := utils.Rc.RedisString(STSTokenCacheKey)
	if recent != "" {
		lastToken := new(STSToken)
		if e := json.Unmarshal([]byte(recent), &lastToken); e != nil {
			err = errors.New("GetOssSTSToken lastToken Unmarshal Err: " + e.Error())
			return
		}
		// 未防止正在上传大文件时Token过期, 将判定的过期时间提前10分钟
		afterTime := time.Now().Local().Add(10 * time.Minute)
		expired, e := time.ParseInLocation(utils.FormatDateTime, lastToken.ExpiredTime, time.Local)
		if e != nil {
			err = errors.New("GetOssSTSToken expiredTime Parse Err: " + e.Error())
			return
		}
		if expired.After(afterTime) {
			item.AccessKeyId = lastToken.AccessKeyId
			item.AccessKeySecret = lastToken.AccessKeySecret
			item.SecurityToken = lastToken.SecurityToken
			item.ExpiredTime = lastToken.ExpiredTime
			return
		}
	}
	// 已过期则获取新的token
	newToken, e := NewSTSToken()
	if e != nil {
		err = errors.New("GetOssSTSToken NewSTSToken Err: " + e.Error())
		return
	}
	newTokenJson, e := json.Marshal(newToken)
	if e != nil {
		err = errors.New("GetOssSTSToken NewToken JSON Err: " + e.Error())
		return
	}
	// 覆盖缓存
	if e := utils.Rc.Put(STSTokenCacheKey, newTokenJson, time.Hour); e != nil {
		err = errors.New("GetOssSTSToken SetRedis Err: " + e.Error())
		return
	}
	item = newToken
	return
}

// NewSTSToken 获取一个新的STSToken
func NewSTSToken() (item *STSToken, err error) {
	defer func() {
		if err != nil {
			utils.FileLog.Info(err.Error())
		}
	}()
	item = new(STSToken)
	client, e := sts.NewClientWithAccessKey("cn-shanghai", RAMAccessKeyId, RAMAccessKeySecret)
	if e != nil {
		err = errors.New("NewSTSToken NewClient Err: " + e.Error())
		return
	}
	request := sts.CreateAssumeRoleRequest()
	request.Scheme = "https"
	request.RegionId = "cn-shanghai"
	request.RoleArn = RoleArn
	now := time.Now().Format(utils.FormatDateTimeUnSpace)
	request.RoleSessionName = RoleSessionName + now
	request.DurationSeconds = "3600"

	response, e := client.AssumeRole(request)
	if e != nil {
		err = errors.New("NewSTSToken AssumeRole Err: " + e.Error())
		return
	}
	if response != nil {
		item.AccessKeyId = response.Credentials.AccessKeyId
		item.AccessKeySecret = response.Credentials.AccessKeySecret
		item.SecurityToken = response.Credentials.SecurityToken
		t, _ := time.Parse(time.RFC3339, response.Credentials.Expiration)
		expiration := t.In(time.Local)
		item.ExpiredTime = expiration.Format(utils.FormatDateTime)
	}
	return
}

//后台用于传研报小程序二维码
var (
	Bucketname      string = "hzchart"
	Endpoint        string = "oss-cn-shanghai.aliyuncs.com"
	Imghost         string = "https://hzstatic.hzinsights.com/"
	UploadDir       string = "static/images/"
	AccessKeyId     string = "LTAIFMZYQhS2BTvW"
	AccessKeySecret string = "12kk1ptCHoGWedhBnKRVW5hRJzq9Fq"
)

// UploadAliyunToDir
func UploadAliyunToDir(filename, filepath, fileDir string) (string, error) {
	client, err := oss.New(Endpoint, AccessKeyId, AccessKeySecret)
	if err != nil {
		return "1", err
	}
	bucket, err := client.Bucket(Bucketname)
	if err != nil {
		return "2", err
	}
	if fileDir == "" {
		fileDir = time.Now().Format("200601/20060102/")
	}
	path := UploadDir + fileDir
	path += filename
	err = bucket.PutObjectFromFile(path, filepath)
	if err != nil {
		return "3", err
	}
	path = Imghost + path
	return path, err
}
