package lts

import (
	"bufio"
	"bytes"
	"crypto/hmac"
	"crypto/sha256"
	"crypto/tls"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io"
	"mime/multipart"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"runtime"
	"sort"
	"strings"
	"time"

	"github.com/go-basic/uuid"
)

func Http(contentType, method, url, ak, sk string, headerMap map[string]string, query, body string, fileMap, dataMap map[string]string) string {
	result := ""
	// headerMap := String2Map(header)

	switch method {
	case "get":
		result = GetHttp(contentType, url, ak, sk, headerMap, query)
	case "post":
		if strings.Contains(contentType, "form-data") {
			result = PostHttpForFormData(url, body, ak, sk, headerMap, query, fileMap, dataMap)
		} else if strings.Contains(contentType, "x-www-form-urlencoded") {
			result = PostHttpForForm(contentType, url, body, ak, sk, headerMap, query)
		} else {
			result = PostHttp(contentType, url, body, ak, sk, headerMap, query)
		}
	case "put":
		if strings.Contains(contentType, "xml") {
			result = PutHttpForXml(contentType, url, body, ak, sk, headerMap, query)
		} else {
			result = PutHttp(contentType, url, body, ak, sk, headerMap, query)
		}
	case "delete":
		result = DeleteHttp(contentType, url, body, ak, sk, headerMap, query)
	}
	return result
}

func PostHttpForFormData(url, reqParam, ak, sk string, headerMap map[string]string, query string, fileMap, dataMap map[string]string) string {
	fmt.Println("Content-Type : multipart/form-data 请求参数")
	bodyBuf := &bytes.Buffer{}
	bodyWriter := multipart.NewWriter(bodyBuf)
	//请求类型，例：multipart/form-data; boundary=7d8da3f8862ee22367dc1ea5c015d74dedbb2d834be8f1ef0545dc7f3534
	contentType := bodyWriter.FormDataContentType()

	for temp := range fileMap {
		//key值
		fileNameKey := temp
		//value值
		fileNameVal := fileMap[temp]
		f, err := os.Open(fileNameVal)
		if err != nil {
			return err.Error()
		}
		fileWriter1, err := bodyWriter.CreateFormFile(fileNameKey, filepath.Base(fileNameVal))
		if err != nil {
			return err.Error()
		}
		_, err1 := io.Copy(fileWriter1, f)
		if err1 != nil {
			return err.Error()
		}
		err = bodyWriter.Close()
		if err != nil {
			return err.Error()
		}
	}
	//拼接加密body
	var byteList [][]byte

	fmt.Println("--------------------------------------------------")
	for key, val := range dataMap {
		fileWriter2, err := bodyWriter.CreateFormField(key)
		if err != nil {
			return err.Error()
		}
		_, errs2 := fileWriter2.Write([]byte(val))
		if errs2 != nil {
			return err.Error()
		}
		bodyWriter.Close()
	}
	fmt.Println("--------------------------------------------------")
	var newQuery = ""
	var queryStr = strings.Split(query, "&")
	sort.Slice(queryStr, func(i, j int) bool {
		return queryStr[i] < queryStr[j] // 正序
	})
	for _, value := range queryStr {
		newQuery = newQuery + "&" + value
	}
	afterQuery := EncodeQueryStr(newQuery)
	if afterQuery != "" {
		url = url + "?" + afterQuery
	}
	//获取请求头contentType中的boundary
	boundary := substring(contentType, strings.Index(contentType, "=")+1, len(contentType))
	//获取boundary进行加密
	strings.Split(boundary, ";")
	boundary = "--" + boundary
	fmt.Println(boundary)

	for temp := range fileMap {
		//key值
		fileNameKey := temp
		//value值
		fileNameVal := fileMap[temp]
		//打印
		fmt.Println(fileNameKey, fileNameVal)
		//读取文件计算大小
		fi, _ := os.Stat(fileNameVal)
		size := fi.Size()
		fmt.Println(size)
		// 文件大小限制 1048576bytes = 1024kb = 1M
		if size >= 1048576 {
			fmt.Println("----------------文件过大----------------")
		}
		body1 := boundary + "\r\n" +
			"Content-Disposition: form-data; name=\"" + fileNameKey + "\"; filename=\"" + fi.Name() + "\"\r\n" +
			"Content-Type: application/octet-stream" + "\r\n" + "\r\n"
		fmt.Println(body1)
		body3 := "\r\n"
		order1 := []byte(body1)
		fmt.Println("body1:", len(string(order1)))
		order2 := readByte(fileNameVal)
		fmt.Println("body2:", len(string(order2)))
		order3 := []byte(body3)
		fmt.Println("body3:", len(string(order3)))

		//计算数组长度
		arrLen := len(order1) + len(order2) + len(order3)
		//声明
		bodyArr := make([]byte, arrLen)

		copy(bodyArr, order1)
		for i := 0; i < len(order2); i++ {
			bodyArr[len(order1)+i] = order2[i]
		}
		for i := 0; i < len(order3); i++ {
			bodyArr[len(order1)+len(order2)+i] = order3[i]
		}
		byteList = append(byteList, bodyArr)
	}

	var lengths = 0
	for x := range byteList {
		lengths = lengths + len(byteList[x])
	}
	fmt.Println("byteList 总长度:", lengths)

	bodyArrs := make([]byte, lengths)
	var num = 0
	for x := range byteList {
		for i := 0; i < len(byteList[x]); i++ {
			bodyArrs[num] = byteList[x][i]
			num = num + 1
		}
	}
	fmt.Println("bodyArrs 总长度:", len(bodyArrs))

	dataStr := ""
	if len(dataMap) > 0 {
		for temp := range dataMap {
			//key值
			dataNameKey := temp
			//value值
			dataNameVal := dataMap[temp]
			body := "Content-Disposition: form-data; name=\"" + dataNameKey + "\"\r\n" + "\r\n"
			nameVal := dataNameVal + "\r\n"
			dataStr = dataStr + boundary + "\r\n" + body + nameVal
		}
	}
	dataStrByte := []byte(dataStr)
	fmt.Println("dataStr 总长度:", len(dataStr))

	body4 := boundary + "--\r\n"
	order4 := []byte(body4)
	fmt.Println("order4 长度:", len(order4))

	lastBodyArr := make([]byte, len(bodyArrs)+len(dataStrByte)+len(order4))

	copy(lastBodyArr, bodyArrs)
	for i := 0; i < len(dataStrByte); i++ {
		lastBodyArr[len(bodyArrs)+i] = dataStrByte[i]
	}
	for i := 0; i < len(order4); i++ {
		lastBodyArr[len(bodyArrs)+len(dataStrByte)+i] = order4[i]
	}

	fmt.Println("lastBodyArr 长度:", len(lastBodyArr))

	uuId := uuid.New()
	fmt.Println("----------------------")
	fmt.Println(string(lastBodyArr))
	fmt.Println("----------------------")
	// 准备: HTTP请求
	reqBody := strings.NewReader(string(lastBodyArr))
	httpReq, err := http.NewRequest(http.MethodPost, url, reqBody)
	fmt.Println(url)
	if err != nil {
		fmt.Printf("NewRequest fail, url: %s, reqBody: %s, err: %v", "", bodyBuf, err)
		return err.Error()
	}
	// loc, _ := time.LoadLocation("Asia/Shanghai")  //设置上海时间
	// tim := time.Now().In(loc)
	tim := time.Now()
	eopDate := tim.Format("20060102T150405Z")
	httpReq.Header.Add("ctyun-eop-request-id", uuId)
	httpReq.Header.Add("Eop-Authorization", getSignByByMultipartFormDataBoundary(ak, sk, afterQuery, uuId, tim, lastBodyArr))
	httpReq.Header.Add("Eop-date", eopDate)
	httpReq.Header.Add("Content-Type", bodyWriter.FormDataContentType())
	for temp := range headerMap {
		httpReq.Header.Add(temp, headerMap[temp])
		fmt.Println(temp + ":" + headerMap[temp])
	}
	// DO: HTTP请求
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr}
	httpRsp, err := client.Do(httpReq)
	if err != nil {
		fmt.Printf("do http fail, url: %s, reqBody: %s, err:%v", "", bodyBuf, err)
		return err.Error()
	}
	headers := httpReq.Header
	for k, v := range headers {
		fmt.Println(k, v)
	}

	if httpRsp.StatusCode != http.StatusOK {
		fmt.Println()
		fmt.Println("应答头部 -----: ", httpRsp.Header)
		fmt.Println("请求StatusCode: ", httpRsp.StatusCode)
		fmt.Println()
	}
	defer httpRsp.Body.Close()

	// Read: HTTP结果
	rspBody, err := io.ReadAll(httpRsp.Body)
	fmt.Println("rspBody: " + string(rspBody))
	if err != nil {
		fmt.Printf("ReadAll failed, url: %s, reqBody: %s, err: %v", "", bodyBuf, err)
		return err.Error()
	}
	return string(rspBody)
}

func GetHttp(contentType, url, ak, sk string, headerMap map[string]string, query string) string {
	var queryStr = strings.Split(query, "&")
	sort.Slice(queryStr, func(i, j int) bool {
		return queryStr[i] < queryStr[j]
	})

	newQuery := strings.Join(queryStr, "&")
	afterQuery := EncodeQueryStr(newQuery)
	if query != "" {
		if afterQuery != "" {
			url = url + "?" + afterQuery
		}
	}
	uuId := uuid.New()
	var (
		err error
	)
	// 准备: HTTP请求
	httpReq, err := http.NewRequest(http.MethodGet, url, nil)
	if err != nil {
		return err.Error()
	}
	// loc, _ := time.LoadLocation("Asia/Shanghai")  //设置上海时间
	// tim := time.Now().In(loc)
	tim := time.Now()
	eopDate := tim.Format("20060102T150405Z")

	version := runtime.Version()
	USER_AGENT_PREFIX := "lts-sdk-go"
	useragent := fmt.Sprintf("%s/%s", USER_AGENT_PREFIX, version)

	httpReq.Header.Add("User-Agent", useragent)
	httpReq.Header.Add("Content-Type", contentType)
	httpReq.Header.Add("ctyun-eop-request-id", uuId)
	httpReq.Header.Add("Eop-Authorization", getSign("", uuId, ak, sk, http.MethodGet, tim, afterQuery))
	httpReq.Header.Add("Eop-date", eopDate)

	for temp := range headerMap {
		httpReq.Header.Add(temp, headerMap[temp])
	}

	// DO: HTTP请求
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr}
	httpRsp, err := client.Do(httpReq)
	if err != nil {
		return err.Error()
	}

	defer httpRsp.Body.Close()

	// Read: HTTP结果
	rspBody, err := io.ReadAll(httpRsp.Body)
	if err != nil {
		return err.Error()
	}
	return string(rspBody)
}

func PostHttpForForm(contentType, url1, reqParam, ak, sk string, headerMap map[string]string, query string) string {
	var newQuery = ""
	var queryStr = strings.Split(query, "&")
	sort.Slice(queryStr, func(i, j int) bool {
		return queryStr[i] < queryStr[j] // 正序
	})
	for _, value := range queryStr {
		newQuery = newQuery + "&" + value
	}
	afterQuery := EncodeQueryStr(newQuery)
	if query != "" {
		if afterQuery != "" {
			url1 = url1 + "?" + afterQuery
		}
	}
	uuId := uuid.New()
	var (
		err error
	)

	// 准备表单数据
	badyParam := url.Values{}
	data := make(map[string]string)
	json.Unmarshal([]byte(reqParam), &data)
	for key, value := range data {
		fmt.Println(key, value)
		badyParam.Set(key, value)
	}

	// 准备: HTTP请求
	reqBody := strings.NewReader(badyParam.Encode())
	httpReq, err := http.NewRequest(http.MethodPost, url1, reqBody)
	fmt.Println(url1)
	if err != nil {
		fmt.Printf("NewRequest fail, url: %s, reqBody: %v, err: %v", "", reqBody, err)
		return err.Error()
	}
	// loc, _ := time.LoadLocation("Asia/Shanghai")  //设置上海时间
	// tim := time.Now().In(loc)
	tim := time.Now()
	eopDate := tim.Format("20060102T150405Z")

	httpReq.Header.Add("Content-Type", contentType)
	httpReq.Header.Add("ctyun-eop-request-id", uuId)
	httpReq.Header.Add("Eop-Authorization", getSign(badyParam.Encode(), uuId, ak, sk, http.MethodPost, tim, afterQuery))
	httpReq.Header.Add("Eop-date", eopDate)
	for temp := range headerMap {
		httpReq.Header.Add(temp, headerMap[temp])
	}
	fmt.Println("httpReq.Header:", httpReq.Header)
	// DO: HTTP请求
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr}
	httpRsp, err := client.Do(httpReq)
	if err != nil {
		fmt.Printf("do http fail, url: %s, reqBody: %v, err:%v", "", reqBody, err)
		return err.Error()
	}
	headers := httpReq.Header
	for k, v := range headers {
		fmt.Println(k, v)
	}

	if httpRsp.StatusCode != http.StatusOK {
		fmt.Println()
		fmt.Println("请求StatusCode: ", httpRsp.StatusCode)
		fmt.Println()
	}
	defer httpRsp.Body.Close()

	// Read: HTTP结果
	rspBody, err := io.ReadAll(httpRsp.Body)
	fmt.Println("rspBody: " + string(rspBody))
	if err != nil {
		fmt.Printf("ReadAll failed, url: %s, reqBody: %v, err: %v", "", reqBody, err)
		return err.Error()
	}
	return string(rspBody)
}

func PostHttp(contentType, url1, reqParam, ak, sk string, headerMap map[string]string, query string) string {
	var queryStr = strings.Split(query, "&")
	sort.Slice(queryStr, func(i, j int) bool {
		return queryStr[i] < queryStr[j]
	})

	newQuery := strings.Join(queryStr, "&")
	afterQuery := EncodeQueryStr(newQuery)
	if query != "" {
		if afterQuery != "" {
			url1 = url1 + "?" + afterQuery
		}
	}
	uuId := uuid.New()
	var err error

	// 准备: HTTP请求
	reqBody := strings.NewReader(string(reqParam))
	httpReq, err := http.NewRequest(http.MethodPost, url1, reqBody)
	if err != nil {
		return err.Error()
	}
	// loc, _ := time.LoadLocation("Asia/Shanghai")  //设置上海时间
	// tim := time.Now().In(loc)
	tim := time.Now()
	eopDate := tim.Format("20060102T150405Z")
	version := runtime.Version()
	USER_AGENT_PREFIX := "lts-sdk-go"
	useragent := fmt.Sprintf("%s/%s", USER_AGENT_PREFIX, version)

	httpReq.Header.Add("User-Agent", useragent)
	httpReq.Header.Add("Content-Type", contentType)
	httpReq.Header.Add("ctyun-eop-request-id", uuId)
	httpReq.Header.Add("Eop-Authorization", getSign(string(reqParam), uuId, ak, sk, http.MethodPost, tim, afterQuery))
	httpReq.Header.Add("Eop-date", eopDate)
	for temp := range headerMap {
		httpReq.Header.Add(temp, headerMap[temp])
	}

	// DO: HTTP请求
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr}
	httpRsp, err := client.Do(httpReq)
	if err != nil {
		return err.Error()
	}

	defer httpRsp.Body.Close()

	// Read: HTTP结果
	rspBody, err := io.ReadAll(httpRsp.Body)
	if err != nil {
		return err.Error()
	}
	return string(rspBody)
}

func PutHttp(contentType, url, reqParam, ak, sk string, headerMap map[string]string, query string) string {
	var newQuery = ""
	var queryStr = strings.Split(query, "&")
	sort.Slice(queryStr, func(i, j int) bool {
		return queryStr[i] < queryStr[j] // 正序
	})
	for _, value := range queryStr {
		newQuery = newQuery + "&" + value
	}
	afterQuery := EncodeQueryStr(newQuery)
	if query != "" {
		if afterQuery != "" {
			url = url + "?" + afterQuery
		}
	}
	uuId := uuid.New()
	var (
		err error
	)
	// 准备: HTTP请求
	reqBody := strings.NewReader(string(reqParam))
	httpReq, err := http.NewRequest(http.MethodPut, url, reqBody)
	fmt.Println(url)
	if err != nil {
		// fmt.Printf("NewRequest fail, url: %s, reqBody: %s, err: %v", "", reqBody, err)
		return err.Error()
	}
	// loc, _ := time.LoadLocation("Asia/Shanghai")  //设置上海时间
	// tim := time.Now().In(loc)
	tim := time.Now()
	eopDate := tim.Format("20060102T150405Z")

	httpReq.Header.Add("Content-Type", contentType)
	httpReq.Header.Add("ctyun-eop-request-id", uuId)
	httpReq.Header.Add("Eop-Authorization", getSign(reqParam, uuId, ak, sk, http.MethodPut, tim, afterQuery))
	httpReq.Header.Add("Eop-date", eopDate)
	for temp := range headerMap {
		httpReq.Header.Add(temp, headerMap[temp])
	}
	// DO: HTTP请求
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr}
	httpRsp, err := client.Do(httpReq)
	if err != nil {
		// fmt.Printf("do http fail, url: %s, reqBody: %s, err:%v", "", reqBody, err)
		return err.Error()
	}
	headers := httpReq.Header
	for k, v := range headers {
		fmt.Println(k, v)
	}

	if httpRsp.StatusCode != http.StatusOK {
		fmt.Println()
		fmt.Println("请求StatusCode: ", httpRsp.StatusCode)
		fmt.Println()
	}
	defer httpRsp.Body.Close()

	// Read: HTTP结果
	rspBody, err := io.ReadAll(httpRsp.Body)
	fmt.Println("rspBody: " + string(rspBody))
	if err != nil {
		// fmt.Printf("ReadAll failed, url: %s, reqBody: %s, err: %v", "", reqBody, err)
		return err.Error()
	}
	return string(rspBody)
}

func PutHttpForXml(contentType, url, reqParam, ak, sk string, headerMap map[string]string, query string) string {
	var newQuery = ""
	var queryStr = strings.Split(query, "&")
	sort.Slice(queryStr, func(i, j int) bool {
		return queryStr[i] < queryStr[j] // 正序
	})
	for _, value := range queryStr {
		newQuery = newQuery + "&" + value
	}
	afterQuery := EncodeQueryStr(newQuery)
	if query != "" {
		if afterQuery != "" {
			url = url + "?" + afterQuery
		}
	}
	uuId := uuid.New()
	var (
		err error
	)
	// 准备: HTTP请求
	reqBody := strings.NewReader(string(reqParam))
	httpReq, err := http.NewRequest(http.MethodPut, url, reqBody)
	fmt.Println(url)
	if err != nil {
		// fmt.Printf("NewRequest fail, url: %s, reqBody: %s, err: %v", "", reqBody, err)
		return err.Error()
	}
	// loc, _ := time.LoadLocation("Asia/Shanghai")  //设置上海时间
	// tim := time.Now().In(loc)
	tim := time.Now()
	eopDate := tim.Format("20060102T150405Z")

	httpReq.Header.Add("Content-Type", contentType)
	httpReq.Header.Add("ctyun-eop-request-id", uuId)
	httpReq.Header.Add("Eop-Authorization", getSign(reqParam, uuId, ak, sk, http.MethodPut, tim, afterQuery))
	httpReq.Header.Add("Eop-date", eopDate)
	for temp := range headerMap {
		httpReq.Header.Add(temp, headerMap[temp])
	}
	// DO: HTTP请求
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr}
	httpRsp, err := client.Do(httpReq)
	if err != nil {
		// fmt.Printf("do http fail, url: %s, reqBody: %s, err:%v", "", reqBody, err)
		return err.Error()
	}
	headers := httpReq.Header
	for k, v := range headers {
		fmt.Println(k, v)
	}

	if httpRsp.StatusCode != http.StatusOK {
		fmt.Println()
		fmt.Println("请求StatusCode: ", httpRsp.StatusCode)
		fmt.Println()
	}
	defer httpRsp.Body.Close()

	// Read: HTTP结果
	rspBody, err := io.ReadAll(httpRsp.Body)
	fmt.Println("rspBody: " + string(rspBody))
	if err != nil {
		// fmt.Printf("ReadAll failed, url: %s, reqBody: %s, err: %v", "", reqBody, err)
		return err.Error()
	}
	return string(rspBody)
}

func DeleteHttp(contentType, url, reqParam, ak, sk string, headerMap map[string]string, query string) string {
	var newQuery = ""
	var queryStr = strings.Split(query, "&")
	sort.Slice(queryStr, func(i, j int) bool {
		return queryStr[i] < queryStr[j] // 正序
	})
	for _, value := range queryStr {
		newQuery = newQuery + "&" + value
	}
	afterQuery := EncodeQueryStr(newQuery)
	if query != "" {
		if afterQuery != "" {
			url = url + "?" + afterQuery
		}
	}
	uuId := uuid.New()
	var (
		err error
	)
	// 准备: HTTP请求
	reqBody := strings.NewReader(string(reqParam))
	httpReq, err := http.NewRequest(http.MethodDelete, url, reqBody)
	fmt.Println(url)
	if err != nil {
		// fmt.Printf("NewRequest fail, url: %s, reqBody: %s, err: %v", "", reqBody, err)
		return err.Error()
	}
	// loc, _ := time.LoadLocation("Asia/Shanghai")  //设置上海时间
	// tim := time.Now().In(loc)
	tim := time.Now()
	eopDate := tim.Format("20060102T150405Z")

	httpReq.Header.Add("Content-Type", contentType)
	httpReq.Header.Add("ctyun-eop-request-id", uuId)
	httpReq.Header.Add("Eop-Authorization", getSign(reqParam, uuId, ak, sk, http.MethodDelete, tim, afterQuery))
	httpReq.Header.Add("Eop-date", eopDate)
	for temp := range headerMap {
		httpReq.Header.Add(temp, headerMap[temp])
	}
	// DO: HTTP请求
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr}
	httpRsp, err := client.Do(httpReq)
	if err != nil {
		// fmt.Printf("do http fail, url: %s, reqBody: %s, err:%v", "", reqBody, err)
		return err.Error()
	}
	headers := httpReq.Header
	for k, v := range headers {
		fmt.Println(k, v)
	}

	if httpRsp.StatusCode != http.StatusOK {
		fmt.Println()
		fmt.Println("请求StatusCode: ", httpRsp.StatusCode)
		fmt.Println()
	}
	defer httpRsp.Body.Close()

	// Read: HTTP结果
	rspBody, err := io.ReadAll(httpRsp.Body)
	fmt.Println("rspBody: " + string(rspBody))
	if err != nil {
		// fmt.Printf("ReadAll failed, url: %s, reqBody: %s, err: %v", "", reqBody, err)
		return err.Error()
	}
	return string(rspBody)
}

func getSign(body, uuId, ak, sk, method string, tim time.Time, afterQuery string) string {
	// fmt.Println("body:" + body)
	data := []byte(body)
	// hash
	hash := sha256.New()
	hash.Write(data)
	sum1 := hash.Sum(nil)
	calculateContentHash := hex.EncodeToString(sum1)

	var sigture string

	singerDate := tim.Format("20060102T150405Z")
	singerDd := tim.Format("20060102")
	CampmocalHeader := "ctyun-eop-request-id:" + uuId + "\neop-date:" + singerDate + "\n"
	if method == http.MethodGet {
		if afterQuery == "=&=" {
			sigture = CampmocalHeader + "\n" + "" + "\n" + calculateContentHash
		} else {
			sigture = CampmocalHeader + "\n" + afterQuery + "\n" + calculateContentHash
		}
		// fmt.Println("sigture:", sigture)
	} else {
		if afterQuery == "=&=" {
			sigture = CampmocalHeader + "\n" + "" + "\n" + calculateContentHash
		} else {
			sigture = CampmocalHeader + "\n" + afterQuery + "\n" + calculateContentHash
		}
	}
	kSecret := sk
	ktime := HmacSHA256(singerDate, kSecret)
	kAk := HmacSHA256(ak, string(ktime))
	kdate := HmacSHA256(singerDd, string(kAk))
	signaSha256 := HmacSHA256(sigture, string(kdate))
	Signature := base64.StdEncoding.EncodeToString(signaSha256)
	signHeader := ak + " Headers=ctyun-eop-request-id;eop-date Signature=" + Signature
	// fmt.Println("signHeader: " ,signHeader)
	// fmt.Println()
	// fmt.Println()
	return signHeader
}

func getSignByByMultipartFormDataBoundary(ak, sk, afterQuery, uuId string, tim time.Time, bodyArr []byte) string {
	fmt.Println("---------------------------开始---------------------------")
	fmt.Println(string(bodyArr))
	fmt.Println("---------------------------结束---------------------------")
	// hash
	hash := sha256.New()
	hash.Write(bodyArr)
	sum1 := hash.Sum(nil)
	calculateContentHash := hex.EncodeToString(sum1)

	var sigture string

	singerDate := tim.Format("20060102T150405Z")
	singerDd := tim.Format("20060102")
	CampmocalHeader := "ctyun-eop-request-id:" + uuId + "\neop-date:" + singerDate + "\n"
	sigture = CampmocalHeader + "\n" + afterQuery + "\n" + calculateContentHash
	fmt.Println("sigture: " + sigture)
	kSecret := sk
	ktime := HmacSHA256(singerDate, kSecret)
	fmt.Println("ktime: " + hex.EncodeToString(ktime))
	kAk := HmacSHA256(ak, string(ktime))
	fmt.Println("kAk: " + hex.EncodeToString(kAk))
	kdate := HmacSHA256(singerDd, string(kAk))
	fmt.Println("kdate: " + hex.EncodeToString(kdate))
	signaSha256 := HmacSHA256(sigture, string(kdate))
	Signature := base64.StdEncoding.EncodeToString(signaSha256)
	fmt.Println("Signature: " + Signature)
	signHeader := ak + " Headers=ctyun-eop-request-id;eop-date Signature=" + Signature
	fmt.Println("signHeader: " + signHeader)
	fmt.Println()
	fmt.Println()
	return signHeader
}

func EncodeQueryStr(query string) string {
	afterQuery := ""
	if len(query) != 0 {
		n := strings.Split(query, "&")
		for _, v := range n {
			if len(afterQuery) < 1 {
				a := strings.Split(v, "=")
				if len(a) >= 2 {
					encodeStr := url.QueryEscape(a[1])
					v = a[0] + "=" + encodeStr
					afterQuery = afterQuery + v
				} else {
					encodeStr := ""
					v = a[0] + "=" + encodeStr
					afterQuery = afterQuery + v
				}
			} else {
				a := strings.Split(v, "=")
				if len(a) >= 2 {
					encodeStr := url.QueryEscape(a[1])
					v = a[0] + "=" + encodeStr
					afterQuery = afterQuery + "&" + v
				} else {
					encodeStr := ""
					v = a[0] + "=" + encodeStr
					afterQuery = afterQuery + "&" + v
				}
			}
		}
	}

	return afterQuery
}

func HmacSHA256(signature, key string) []byte {
	s := []byte(signature)
	k := []byte(key)
	m := hmac.New(sha256.New, k)
	m.Write(s)
	sum1 := m.Sum(nil)
	return sum1
}

func MapInterface2String(inputData map[string]interface{}) map[string]string {
	outputData := map[string]string{}
	for key, value := range inputData {
		switch v := value.(type) {
		case string:
			outputData[key] = v
		}
	}
	return outputData
}

func String2Map(header string) map[string]string {
	data := []byte(header)
	map2 := make(map[string]interface{})
	err := json.Unmarshal(data, &map2)
	if err != nil {
		fmt.Println(err)
	}
	headerMap := MapInterface2String(map2)
	return headerMap
}

func JSONMethod(content interface{}) map[string]interface{} {
	var name map[string]interface{}
	if marshalContent, err := json.Marshal(content); err != nil {
		fmt.Println(err)
	} else {
		d := json.NewDecoder(bytes.NewReader(marshalContent))
		d.UseNumber() // 设置将float64转为一个number
		if err := d.Decode(&name); err != nil {
			fmt.Println(err)
		} else {
			for k, v := range name {
				name[k] = v
			}
		}
	}
	return name
}

func substring(source string, start int, end int) string {
	var r = []rune(source)
	length := len(r)

	if start < 0 || end > length || start > end {
		return ""
	}

	if start == 0 && end == length {
		return source
	}

	return string(r[start:end])
}

func readByte(fileName string) []byte {
	result := ""
	//打开文件
	file, err := os.Open(fileName)
	if err != nil {
		fmt.Println("文件打开失败 = ", err)
	}
	//当函数退出时及时关闭file
	//defer在函数结束之前会调用defer后的代码
	//及时关闭file句柄，否则会有内存泄漏
	defer file.Close()
	//创建一个 *Reader ， 是带缓冲的
	reader := bufio.NewReader(file)
	for {
		str, err := reader.ReadString('\n') //读到一个换行就结束
		result = result + str
		if err == io.EOF { //io.EOF表示文件的末尾
			return []byte(result)
		}
	}
}
