package httpclient

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"../log"
	"time"

	"go.uber.org/zap"
)

func newHTTPClient() *http.Client {
	return &http.Client{
		Transport: &http.Transport{
			Dial: func(network, addr string) (net.Conn, error) {
				deadline := time.Now().Add(time.Millisecond * 500)
				c, err := net.DialTimeout(network, addr, time.Second)
				if err != nil {
					return nil, err
				}
				c.SetDeadline(deadline)
				return c, nil
			},
		},
	}
}

var emptyBytes = []byte("")

func HTTPPost(url string, requestData interface{}) ([]byte, int, error) {
	ReqData, _ := json.Marshal(requestData)

	req, err := http.NewRequest("POST", url, bytes.NewReader(ReqData))
	if err != nil {
		log.Info("httpPost NewRequest error:", zap.Error(err))
		return emptyBytes, 0, err
	}

	client := newHTTPClient()
	start := time.Now()
	resp, err := client.Do(req)
	if err != nil {
		end := time.Now()
		log.Info("httpPost Do error", zap.Time("start", start), zap.Time("end", end), zap.Duration("cost(s)", end.Sub(start)), zap.Error(err))
		return emptyBytes, 0, err
	}

	defer resp.Body.Close()

	statusCode := resp.StatusCode
	if statusCode != http.StatusOK {
		log.Info("httpPost error:", zap.Error(fmt.Errorf("get http.statusCode %d", statusCode)))
		return emptyBytes, statusCode, nil
	}

	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Info("httpPost error:", zap.Error(err))
		return emptyBytes, 0, err
	}
	return data, http.StatusOK, nil
}
