package tool

import (
	"fmt"
	"github.com/qiniu/go-sdk/v7/storage"
	"io"
	"net/http"
	"os"
	"strings"
	"time"
)

//此函数为将用户名密码通过指定方式生成鉴权信息:
//func generateSignature(userStringToSign, userAK, userSK string) (res string) {
//	key := []byte(userSK)
//	mac := hmac.New(sha1.New, key)
//	mac.Write([]byte(userStringToSign))
//	signature := base64.StdEncoding.EncodeToString(mac.Sum(nil))
//	res = "AUTH "+ userAK + ":" + signature
//	return
//}

func DownloadFile(url, path string) (pathRes, downloadRes bool) {
	var res *http.Response
	tt := strings.Split(path, "/")
	pathDir := strings.TrimSuffix(path, tt[len(tt)-1])
	pathDir = strings.TrimSuffix(pathDir, "/")
	err := os.MkdirAll(pathDir, 0777)
	if err != nil {
		fmt.Printf("mkdir file failed:[%s], error:[%v], path:[%s]\n", pathDir, err, path)
		return false, false
	} else {
		fmt.Printf("mkdir file success:[%s], error:[%v], path:[%s]\n", pathDir, err, path)
	}
	_ = os.Remove(path)
	buffer, err := os.Create(path)
	if err != nil {
		fmt.Printf("open file failed, error:%v, path:[%s]\n", err, path)
		return false, false
	} else {
		fmt.Printf("open file success, error:%v, path:[%s]\n", err, path)
	}
	defer buffer.Close()
	//flag 0:work; 1:fail; 2:over
	flag := 0
	for i := 0; i < 3; i++ {
		for {
			//res, err = http.Get(url)
			client := &http.Client{}
			req, err2 := http.NewRequest("GET", url, nil)
			if err2 != nil {
				fmt.Printf("make new http request [%s] error: [%v]\n", url, err2)
				return true, false
			}
			currentDate := time.Now().Format("Mon, 02 Jan 2006 15:04:05 GMT")

			//(可选)如需鉴权操作,则通过以下方式生成Authorization所需内容
			//othersInfo := "xxx"
			//	生成鉴权信息时所需的信息字符串拼接,此处根据具体业务需求更改:
			//stringToSign := "GET" + "\n" + "" + "\n" + "" + "\n" + currentDate + "\n" + "/" + othersInfo
			//需要鉴权则用这个生成鉴权信息,然后放到请求头中:
			//auth := generateSignature(stringToSign, ak, sk)
			//fmt.Printf("Authorization:[%s]\n",auth)

			req.Header.Add("Date", currentDate)
			//req.Header.Add("Authorization", auth)
			//req.Header.Add("Content-Type","video/mp4")
			res, err2 = client.Do(req)
			if err2 != nil {
				fmt.Printf("send http req [%s] error: [%v]\n", url, err2)
				return true, false
			}

			if res.StatusCode != 200 {
				fmt.Printf("download failed:[%s], StatusCode:[%d],url:[%s]\n", path, res.StatusCode, url)
				res.Body.Close()
				if i >= 2 {
					return true, false
				} else {
					flag = 1
					break
				}
			}
			flag = 0
			break
		}
		if flag == 1 {
			time.Sleep(1 * time.Second)
			continue
		}
		buf := make([]byte, 102400)

		for {
			n, err := res.Body.Read(buf)
			if err != nil && err != io.EOF {
				fmt.Printf("Download failed:[%s], error:%v, path:[%s]\n", url, err, path)
				res.Body.Close()
				if i >= 2 {
					return true, false
				} else {
					flag = 1
					break
				}
			}
			buffer.Write(buf[:n])
			if err == io.EOF {
				res.Body.Close()
				flag = 2
				break
			}
		}
		if flag == 1 {
			time.Sleep(1 * time.Second)
			continue
		} else if flag == 2 {
			break
		}
	}
	fmt.Printf("Download success:[%s], path:[%s]\n", url, path)
	return true, true
}

func Zone(zoneStr string) *storage.Region {
	zone := &storage.ZoneHuadong
	switch {
	case zoneStr == "hd":
		zone = &storage.ZoneHuadong
	case zoneStr == "hb":
		zone = &storage.ZoneHuabei
	case zoneStr == "hn":
		zone = &storage.ZoneHuanan
	case zoneStr == "xkp":
		zone = &storage.ZoneXinjiapo
	default:
		zone = &storage.ZoneHuadong
	}
	return zone
}