package admin

import (
	c "ciyon/zciyon"
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"net/http"
	"time"
)

func Upload_upload(w http.ResponseWriter, r *http.Request) bool {
	uploadcfg := map[string][]string{
		"exts":   {"jpe", "jpg", "jpeg", "gif", "png", "ai", "bmp", "psb", "psd", "tif", "svg", "webp", "zip", "7z", "rar", "tar", "arj", "iso", "cab", "gz", "txt", "csv", "doc", "docx", "pps", "ppt", "pptx", "pdf", "wps", "wpt", "xls", "xlsx", "xml", "et", "ett", "avi", "mp4", "mp3", "swf", "flv", "f4v", "m4v", "wma", "rm", "rmvb", "3gp", "ts", "mts", "vob", "mpg", "mpeg", "mov", "wmv", "wav", "bak", "cad", "chm", "log", "ai", "ico"},
		"noexts": {"goc", "php", "php3", "php4", "phtm", "phtml", "php5", "js", "html", "htm", "sh", "so"},
	}
	extselect := "exts"

	post := c.NewCiyPost(w, r)
	_, userid := Verifyfast(r, c.CiyDB, post)
	if userid == 0 {
		return false
	}
	path := post.Get("pathfile")
	file := post.Getfile()
	// if file.content == nil {
	// 	return c.ErrJSON(w, fmt.Sprintf("文件上传错误"))
	// }
	// if file.Size != len(file.content) {
	// 	return c.ErrJSON(w, fmt.Sprintf("文件大小不匹配:%d!=%d", file.Size, len(file.content)))
	// }
	_, extfile := c.Fileext(file.Filename)
	if extselect == "exts" {
		if c.In_array(uploadcfg[extselect], extfile) == -1 {
			return c.ErrJSON(w, "不允许上传"+extfile+"类型文件")
		}
	} else {
		if c.In_array(uploadcfg[extselect], extfile) > -1 {
			return c.ErrJSON(w, "禁止上传"+extfile+"类型文件")
		}
	}
	json, err := c.SaveUploadFile(path, file)
	if err != nil {
		return c.ErrJSON(w, err.Error())
	}
	return c.SuccJSON(w, r, json)
}

func Upload_s3(w http.ResponseWriter, r *http.Request) bool {
	post := c.NewCiyPost(w, r)
	_, userid := Verifyfast(r, c.CiyDB, post)
	if userid == 0 {
		return false
	}
	path := post.Get("pathfile")
	storselect := post.Get("storselect")
	accessKey := c.CiyVars.Ini.GetKey("s3"+storselect, "access", "")
	secretKey := c.CiyVars.Ini.GetKey("s3"+storselect, "secret", "")
	endpoint := c.CiyVars.Ini.GetKey("s3"+storselect, "endpoint", "")
	region := c.CiyVars.Ini.GetKey("s3"+storselect, "region", "")
	bucket := c.CiyVars.Ini.GetKey("s3"+storselect, "bucket", "")
	acl := c.CiyVars.Ini.GetKey("s3"+storselect, "acl", "")
	objectKey := "ud/" + path
	vsha256 := "UNSIGNED-PAYLOAD"
	zdate := time.Now().UTC().Format("20060102T150405Z")
	shortDate := zdate[0:8]
	dateKey := sign([]byte("AWS4"+secretKey), shortDate)
	regionKey := sign(dateKey, region)
	serviceKey := sign(regionKey, "s3")
	signingKey := sign(serviceKey, "aws4_request")
	canonicalUri := "/" + bucket + "/" + objectKey
	canonicalQueryString := ""
	canonicalHeaders := "host:" + endpoint + "\n" +
		"x-amz-acl:" + acl + "\n" +
		"x-amz-content-sha256:" + vsha256 + "\n" +
		"x-amz-date:" + zdate + "\n"
	signedHeaders := "host;x-amz-acl;x-amz-content-sha256;x-amz-date"
	canonicalRequest := "PUT\n" +
		canonicalUri + "\n" +
		canonicalQueryString + "\n" +
		canonicalHeaders + "\n" +
		signedHeaders + "\n" +
		vsha256
	stringToSign := "AWS4-HMAC-SHA256\n" +
		zdate + "\n" +
		shortDate + "/" + region + "/s3/aws4_request\n" +
		sha256Hex(canonicalRequest)
	signature := sign([]byte(signingKey), stringToSign)
	authorizationHeader := "AWS4-HMAC-SHA256 Credential=" + accessKey + "/" + shortDate + "/" + region + "/s3/aws4_request, SignedHeaders=" + signedHeaders + ", Signature=" + hex.EncodeToString(signature)
	ret := make(map[string]interface{})
	ret["method"] = "PUT"
	ret["url"] = "https://" + endpoint + "/" + bucket + "/" + objectKey
	headers := make(map[string]string)
	headers["Authorization"] = authorizationHeader
	headers["x-amz-acl"] = acl
	headers["x-amz-content-sha256"] = vsha256
	headers["x-amz-date"] = zdate
	ret["headers"] = headers
	return c.SuccJSON(w, r, ret)
}

func sign(key []byte, msg string) []byte {
	h := hmac.New(sha256.New, key)
	h.Write([]byte(msg))
	return h.Sum(nil)
}

func sha256Hex(data string) string {
	hash := sha256.New()
	hash.Write([]byte(data))
	return hex.EncodeToString(hash.Sum(nil))
}
