/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package rest

import (
	"bytes"
	"compress/gzip"
	"encoding/json"
	"fmt"
	"github.com/apache/incubator-servicecomb-service-center/pkg/util"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"reflect"
	"time"
)

const (
	DEFAULT_TLS_HANDSHAKE_TIMEOUT = 30 * time.Second
	DEFAULT_HTTP_RESPONSE_TIMEOUT = 10 * time.Second
	DEFAULT_REQUEST_TIMEOUT       = 300 * time.Second

	HTTP_ERROR_STATUS_CODE = 600
)

type HttpClient struct {
	gzip   bool
	Client *http.Client
}

func NewDialer() *net.Dialer {
	return &net.Dialer{
		Timeout:   5 * time.Second,
		KeepAlive: 30 * time.Second,
	}
}

func NewTransport() *http.Transport {
	return &http.Transport{
		Dial:                  NewDialer().Dial,
		MaxIdleConnsPerHost:   5,
		ResponseHeaderTimeout: DEFAULT_HTTP_RESPONSE_TIMEOUT,
		TLSHandshakeTimeout:   DEFAULT_TLS_HANDSHAKE_TIMEOUT,
	}
}

/**
  获取普通HTTP客户端
*/

func GetHttpClient(gzip bool) (client *HttpClient, err error) {
	return &HttpClient{
		gzip: gzip,
		Client: &http.Client{
			Transport: NewTransport(),
			Timeout:   DEFAULT_REQUEST_TIMEOUT,
		},
	}, nil
}

func GetClient() (*HttpClient, error) {
	return GetHttpClient(false)
}

func (client *HttpClient) getHeaders(method string, headers map[string]string, body interface{}) map[string]string {
	newHeaders := make(map[string]string)
	if body != nil {
		newHeaders[HEADER_CONTENT_TYPE] = CONTENT_TYPE_JSON
		newHeaders[HEADER_ACCEPT] = ACCEPT_JSON
	}

	if client.gzip {
		newHeaders[HEADER_ACCEPT_ENCODING] = ENCODING_GZIP
		newHeaders[HEADER_CONTENT_ENCODING] = ENCODING_GZIP
	}

	if headers != nil {
		for key, value := range headers {
			newHeaders[key] = value
		}
	}

	return newHeaders
}

func gzipCompress(src []byte) (dst []byte) {
	var byteBuffer bytes.Buffer

	func() {
		gzipWriter := gzip.NewWriter(&byteBuffer)
		defer gzipWriter.Close()
		gzipWriter.Write(src)
	}()

	return byteBuffer.Bytes()
}

func readAndGunzip(reader io.Reader) (dst []byte, err error) {
	gzipReader, err := gzip.NewReader(reader)
	if err != nil {
		util.Logger().Errorf(err, "duplicate gzip reader failed.")
		return nil, err
	}

	defer gzipReader.Close()
	dst, err = ioutil.ReadAll(gzipReader)
	if err != nil {
		util.Logger().Errorf(err, "read from gzip reader failed.")
		return nil, err
	}

	return dst, nil
}

func (client *HttpClient) httpDo(method string, url string, headers map[string]string, body interface{}) (int, string) {
	status, result := HTTP_ERROR_STATUS_CODE, ""

	var bodyBytes []byte = nil
	var err error = nil
	var bodyReader io.Reader = nil
	if body != nil {
		if headers == nil || len(headers[HEADER_CONTENT_TYPE]) == 0 {
			// 如果请求头未传入Content-Type，则按照json格式进行编码（如果是非json类型，需要自行在headers里指定类型）
			bodyBytes, err = json.Marshal(body)
			if err != nil {
				util.Logger().Errorf(err, "marshal object failed.")
				return status, result
			}
		} else {
			// 如果指定了Content-Type类型，则传入的body必须为byte流
			var ok bool = false
			bodyBytes, ok = body.([]byte)
			if !ok {
				util.Logger().Errorf(nil, "invalid body type '%s'(%s), body must type of byte array if Content-Type specified.", reflect.TypeOf(body), headers[HEADER_CONTENT_TYPE])
				return status, result
			}
		}

		//如果配置了gzip压缩，则对body压缩一次(如果请求头里传入已经gzip压缩了，则不重复压缩)
		if client.gzip && (headers == nil || headers[HEADER_CONTENT_ENCODING] != ENCODING_GZIP) {
			bodyBytes = gzipCompress(bodyBytes)
		}

		bodyReader = bytes.NewBuffer(bodyBytes)
	}

	req, err := http.NewRequest(method, url, bodyReader)
	if err != nil {
		util.Logger().Errorf(err, "create request failed.")
		return status, result
	}

	newHeaders := client.getHeaders(method, headers, body)
	for key, value := range newHeaders {
		req.Header.Set(key, value)
	}

	resp, err := client.Client.Do(req)
	if err != nil {
		util.Logger().Errorf(err, "invoke request failed.")
		return status, result
	}

	defer resp.Body.Close()
	status = resp.StatusCode
	var respBody []byte
	if resp.Header.Get(HEADER_CONTENT_ENCODING) == ENCODING_GZIP {
		// 如果响应头里包含了响应消息的压缩格式为gzip，则在返回前先解压缩
		respBody, _ = readAndGunzip(resp.Body)
	} else {
		respBody, _ = ioutil.ReadAll(resp.Body)
	}
	result = util.BytesToStringWithNoCopy(respBody)

	return status, result
}

func (client *HttpClient) HttpDo(method string, url string, headers map[string]string, body interface{}) (*http.Response, error) {
	var bodyBytes []byte = nil
	var err error = nil
	var bodyReader io.Reader = nil
	if body != nil {
		if headers == nil || len(headers[HEADER_CONTENT_TYPE]) == 0 {
			// 如果请求头未传入Conent-Type，则按照json格式进行编码（如果是非json类型，需要自行在headers里指定类型）
			bodyBytes, err = json.Marshal(body)
			if err != nil {
				util.Logger().Errorf(err, "marshal object failed.")
				return nil, err
			}
		} else {
			// 如果指定了Content-Type类型，则传入的body必须为byte流
			var ok bool = false
			bodyBytes, ok = body.([]byte)
			if !ok {
				err := fmt.Errorf("invalid body type '%s'(%s), body must type of byte array if Content-Type specified.",
					reflect.TypeOf(body), headers[HEADER_CONTENT_TYPE])
				util.Logger().Errorf(err, "")
				return nil, err
			}
		}

		//如果配置了gzip压缩，则对body压缩一次(如果请求头里传入已经gzip压缩了，则不重复压缩)
		if client.gzip && (headers == nil || headers[HEADER_CONTENT_ENCODING] != ENCODING_GZIP) {
			bodyBytes = gzipCompress(bodyBytes)
		}

		bodyReader = bytes.NewBuffer(bodyBytes)
	}

	req, err := http.NewRequest(method, url, bodyReader)
	if err != nil {
		util.Logger().Errorf(err, "create request failed.")
		return nil, err
	}

	newHeaders := client.getHeaders(method, headers, body)
	for key, value := range newHeaders {
		req.Header.Set(key, value)
	}

	resp, err := client.Client.Do(req)
	if err != nil {
		util.Logger().Errorf(err, "Request -----> %s failed.", url)
		return resp, err
	}
	return resp, err
}

func (client *HttpClient) Get(url string, headers map[string]string) (int, string) {
	return client.httpDo(http.MethodGet, url, headers, nil)
}

func (client *HttpClient) Put(url string, headers map[string]string, body interface{}) (int, string) {
	return client.httpDo(http.MethodPut, url, headers, body)
}

func (client *HttpClient) Post(url string, headers map[string]string, body interface{}) (int, string) {
	return client.httpDo(http.MethodPost, url, headers, body)
}

func (client *HttpClient) Delete(url string, headers map[string]string) (int, string) {
	return client.httpDo(http.MethodDelete, url, headers, nil)
}

func (client *HttpClient) Do(req *http.Request) (*http.Response, error) {
	return client.Client.Do(req)
}
