package utils

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"net/url"
	"strings"
	"time"
)

func SerializeJson(data interface{}) []byte {
	reply, _ := json.Marshal(data)
	return reply
}

func UnserislizeJson(str string, data interface{}) {
	_ = json.Unmarshal([]byte(str), data)
}

func ChangeData(dataBefore interface{}, dataAfter interface{}) {
	UnserislizeJson(string(SerializeJson(dataBefore)), dataAfter)
}

func RequesBody(reqBody io.ReadCloser) []byte {
	var bodyBytes []byte
	bodyBytes, _ = ioutil.ReadAll(reqBody)
	return bodyBytes
}

// 发送PUT请求
// url：         请求地址
// data：        PUT请求提交的数据
// contentType： 请求体格式，如：application/json
// content：     请求放回的内容
func Put(url string, data interface{}, token string, isPrt int) string {
	// 超时时间：10秒
	client := &http.Client{Timeout: 10 * time.Second}
	if isPrt == 1 {
		fmt.Println("请求地址：" + url)
	}

	jsonStr, _ := json.Marshal(data)
	if isPrt == 1 {
		fmt.Println("请求数据：" + string(jsonStr))
	}

	reqest, err := http.NewRequest("PUT", url, bytes.NewBuffer(jsonStr))

	if token != "" {
		reqest.Header.Add("Authorization", "Bearer "+token)
		fmt.Println("token：" + token)
	}
	reqest.Header.Add("Content-Type", "application/json")
	reqest.Header.Add("Connection", "keep-alive")
	if err != nil {
		fmt.Println(err)
		return ""
	}

	resp, err := client.Do(reqest)
	if err != nil {
		fmt.Println(err)
		return ""
	}
	defer resp.Body.Close()

	result, _ := ioutil.ReadAll(resp.Body)

	if isPrt == 1 {
		fmt.Println("返回数据：" + string(result))
	}
	return string(result)
}

// 发送POST请求
// url：         请求地址
// data：        POST请求提交的数据
// contentType： 请求体格式，如：application/json
// content：     请求放回的内容
func Post(url string, data interface{}, token string, isPrt int) string {
	// 超时时间：10秒
	client := &http.Client{Timeout: 10 * time.Second}
	if isPrt == 1 {
		fmt.Println("请求地址：" + url)
	}

	jsonStr, _ := json.Marshal(data)
	if isPrt == 1 {
		fmt.Println("请求数据：" + string(jsonStr))
	}

	reqest, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))

	if token != "" {
		reqest.Header.Add("Authorization", "Bearer "+token)
		fmt.Println("token：" + token)
	}
	reqest.Header.Add("Content-Type", "application/json")
	reqest.Header.Add("Connection", "keep-alive")
	if err != nil {
		fmt.Println(err)
		return ""
	}

	resp, err := client.Do(reqest)
	if err != nil {
		fmt.Println(err)
		return ""
	}
	defer resp.Body.Close()

	result, _ := ioutil.ReadAll(resp.Body)

	if isPrt == 1 {
		fmt.Println("返回数据：" + string(result))
	}
	return string(result)
}

func Get(path string, params map[string]string, token string, isPrt int) (string, error) {

	var client = http.Client{
		Timeout: 10 * time.Second,
	}
	defer func() {
		if err := recover(); err != nil {
			fmt.Println("http get err: ", err)
			fmt.Println("client: ", client)
			return
		}
	}()
	param := ""
	if len(params) != 0 {
		param = "?"
		for key, val := range params {
			param += key + "=" + url.QueryEscape(val) + "&"
		}
		param = strings.Trim(param, "&")
	}

	url := path + param

	if isPrt == 1 {
		fmt.Println("请求地址：" + url)
	}

	req, _ := http.NewRequest("GET", url, nil)
	req.Header.Set("Content-Type", "application/json; charset=utf-8")
	if token != "" {
		req.Header.Set("Authorization", "Bearer "+token)
		fmt.Println("token：" + token)
	}
	resp, _ := http.DefaultClient.Do(req)
	body, err := ioutil.ReadAll(resp.Body)

	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	if isPrt == 1 {
		fmt.Println("返回数据：" + string(body))
	}

	return string(body), nil
}

func PostWithFormData(method, url string, postData *map[string]string, token string) string {
	body := new(bytes.Buffer)
	w := multipart.NewWriter(body)
	for k, v := range *postData {
		w.WriteField(k, v)
	}
	w.Close()
	fmt.Println("请求地址：" + url)

	req, _ := http.NewRequest(method, url, body)
	req.Header.Set("Content-Type", w.FormDataContentType())
	if token != "" {
		req.Header.Set("Authorization", "Bearer "+token)
	}
	resp, _ := http.DefaultClient.Do(req)
	data, _ := ioutil.ReadAll(resp.Body)
	resp.Body.Close()
	fmt.Println("HTTP Status：", resp.StatusCode)
	if resp.StatusCode != 200 {
		return "ERROR"
	}
	fmt.Println("返回数据：" + string(data))
	return string(data)
}

func GetIpaddrPostUrl(posturl string, data map[string]string, token string, isPrt int) string {
	// 超时时间：10秒
	client := &http.Client{Timeout: 10 * time.Second}
	if isPrt == 1 {
		fmt.Println("请求地址：" + posturl)
	}

	urlVal := url.Values{}
	for k, v := range data {
		urlVal.Add(k, v)
	}

	jsonStr, _ := json.Marshal(data)
	if isPrt == 1 {
		fmt.Println("请求数据：" + string(jsonStr))
	}

	postData := strings.NewReader(urlVal.Encode())
	reqest, err := http.NewRequest("POST", posturl, postData)

	if token != "" {
		reqest.Header.Add("Authorization", "APPCODE "+token)
		//fmt.Println("token：" + token)
	}
	reqest.Header.Add("Content-Type", "application/x-www-form-urlencoded")
	//reqest.Header.Add("Connection", "keep-alive")
	if err != nil {
		fmt.Println(err)
		return ""
	}

	resp, err := client.Do(reqest)
	if err != nil {
		fmt.Println(err)
		return ""
	}
	defer resp.Body.Close()

	result, _ := ioutil.ReadAll(resp.Body)

	if isPrt == 1 {
		fmt.Println("返回数据：" + string(result))
	}
	return string(result)
}
