package services

import (
	"bytes"
	"eta/eta_mobile/utils"
	"fmt"
	"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"
	"io/ioutil"
	"time"
)

type OssClient interface {
	UploadFile(string, string, string) (string, error)
	GetUploadToken() (OssToken, error)
}

func NewOssClient() OssClient {
	switch utils.ObjectStorageClient {
	case utils.STORAGESOURCE_MINIO_NAME:
		return new(MinioOss)
	case utils.STORAGESOURCE_S3_NAME:
		return new(S3Oss)
	default:
		// 默认使用阿里云OSS
		return new(AliOss)
	}
}

// OssToken 此处为了兼容前端那边所以有重复的
type OssToken struct {
	AccessKeyId string
	SecretKeyId string
	RegionId    string
	Bucketname  string
	Endpoint    string
	ImgHost     string
	UseSSL      string
	Port        string
	//AccessKeyId     string
	AccessKeySecret string
	SecurityToken   string
	ExpiredTime     string
	//RegionId        string
	//Bucketname      string
	//Endpoint        string
	Imghost      string
	S3ForceStyle bool
	S3Protocol   string
}

type S3Oss struct{}

func (m *S3Oss) UploadFile(fileName, localFile, savePath string) (resourceUrl string, err error) {
	defer func() {
		if err != nil {
			fmt.Println(err.Error())
		}
	}()

	endpoint := utils.S3Endpoint
	accessKey := utils.S3AccessKeyId
	secretKey := utils.S3AccessKeySecret
	region := utils.S3Region
	bucketName := utils.S3BucketName
	uploadDir := utils.S3UploadDir
	resourceHost := utils.S3Host
	forceStyle := utils.S3ForceStyle
	hostStyle := true // 默认true, 使用`endpoint/bucket_name`这种HOST格式
	if forceStyle == "false" {
		hostStyle = false
	}

	// 创建AWS会话
	sess, e := session.NewSession(&aws.Config{
		Region:           aws.String(region),
		Credentials:      credentials.NewStaticCredentials(accessKey, secretKey, ""),
		Endpoint:         aws.String(endpoint),
		S3ForcePathStyle: aws.Bool(hostStyle),
	})
	if e != nil {
		err = fmt.Errorf("new session err: %s", e.Error())
		return
	}

	// 创建S3服务客户端
	client := s3.New(sess)

	// 读取文件内容
	fileContent, e := ioutil.ReadFile(localFile)
	if e != nil {
		err = fmt.Errorf("read file err: %s", e.Error())
		return
	}

	path := savePath
	if savePath == "" {
		path = uploadDir + time.Now().Format("200601/20060102/") + fileName
	}
	_, e = client.PutObject(&s3.PutObjectInput{
		Bucket: aws.String(bucketName),
		Key:    aws.String(path),
		Body:   bytes.NewReader(fileContent),
	})
	if e != nil {
		err = fmt.Errorf("put object err: %s", e.Error())
		return
	}
	resourceUrl = resourceHost + path
	return
}

func (m *S3Oss) GetUploadToken() (token OssToken, err error) {
	token.Endpoint = utils.S3Endpoint
	token.AccessKeyId = utils.S3AccessKeyId
	token.AccessKeySecret = utils.S3AccessKeySecret
	token.RegionId = utils.S3Region
	token.Bucketname = utils.S3BucketName
	token.ImgHost = utils.S3Host
	token.Port = utils.S3EndpointPort
	hostStyle := true // 默认true, 使用`endpoint/bucket_name`这种HOST格式
	if utils.S3ForceStyle == "false" {
		hostStyle = false
	}
	token.S3ForceStyle = hostStyle
	token.S3Protocol = utils.S3Protocol
	return
}
